GroupStateHelper.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#ifndef OPM_GROUPSTATEHELPER_HEADER_INCLUDED
20#define OPM_GROUPSTATEHELPER_HEADER_INCLUDED
21
23
24#include <opm/common/TimingMacros.hpp>
25#include <opm/input/eclipse/Schedule/ResCoup/GrupSlav.hpp>
26#include <opm/input/eclipse/EclipseState/Grid/FieldPropsManager.hpp>
27#include <opm/input/eclipse/Schedule/Group/GPMaint.hpp>
28#include <opm/input/eclipse/Schedule/Group/GSatProd.hpp>
29#include <opm/input/eclipse/Schedule/Group/GuideRate.hpp>
30#include <opm/input/eclipse/Schedule/Schedule.hpp>
31#include <opm/input/eclipse/Schedule/ScheduleState.hpp>
32#include <opm/input/eclipse/Schedule/SummaryState.hpp>
33#include <opm/material/fluidsystems/PhaseUsageInfo.hpp>
40
42
43#include <algorithm>
44#include <map>
45#include <memory>
46#include <optional>
47#include <stdexcept>
48#include <string>
49#include <unordered_set>
50#include <vector>
51
52namespace Opm
53{
54
55template <typename Scalar, typename IndexTraits>
57{
58public:
59 // RAII guard for temporarily setting wellstate pointer
61 {
62 public:
64 : groupStateHelper_ {groupStateHelper}
65 , previous_state_ptr_ {groupStateHelper_.well_state_}
66 {
67 // Set the new state directly
68 groupStateHelper_.well_state_ = &well_state;
69 }
70
72 {
73 // Restore the previous state
74 groupStateHelper_.well_state_ = previous_state_ptr_;
75 }
76
77 // Delete copy and move operations
82
83 private:
84 GroupStateHelper& groupStateHelper_;
85 const WellState<Scalar, IndexTraits>* previous_state_ptr_;
86 };
87
88 // RAII guard for temporarily setting groupstate pointer
90 {
91 public:
92 GroupStateGuard(GroupStateHelper& group_state_helper, GroupState<Scalar>& group_state)
93 : group_state_helper_ {group_state_helper}
94 , previous_state_ptr_ {group_state_helper.group_state_}
95 {
96 // Set the new state directly
97 group_state_helper_.group_state_ = &group_state;
98 }
99
101 {
102 // Restore the previous state
103 group_state_helper_.group_state_ = previous_state_ptr_;
104 }
105
106 // Delete copy and move operations
111
112 private:
113 GroupStateHelper& group_state_helper_;
114 GroupState<Scalar>* previous_state_ptr_ {nullptr};
115 };
116
130 {
131 public:
137 explicit ScopedLoggerGuard(const GroupStateHelper& helper, bool do_mpi_gather = true)
138 : helper_(&helper)
139 , previous_(helper.deferred_logger_)
140 , do_mpi_gather_(do_mpi_gather)
141 {
142 helper_->deferred_logger_ = &logger_;
143 }
144
146 {
147 if (helper_) {
148 if (do_mpi_gather_) {
149 // 1. Gather messages across MPI ranks
150 DeferredLogger global = gatherDeferredLogger(logger_, helper_->comm());
151
152 // 2. Log on rank 0 (if terminal_output enabled)
153 if (helper_->terminalOutput()) {
154 global.logMessages();
155 }
156 } else {
157 // Just log locally without MPI gather
158 if (helper_->terminalOutput()) {
159 logger_.logMessages();
160 }
161 }
162
163 // 3. Restore previous logger
164 helper_->deferred_logger_ = previous_;
165 }
166 }
167
168 // Delete copy operations and move assignment
172
173 // Move constructor required for pushLogger() return-by-value (must be
174 // available even if elided by RVO)
176 : helper_(other.helper_)
177 , logger_(std::move(other.logger_))
178 , previous_(other.previous_)
179 , do_mpi_gather_(other.do_mpi_gather_)
180 {
181 // Update the helper's pointer to our moved logger
182 if (helper_) {
183 helper_->deferred_logger_ = &logger_;
184 }
185 other.helper_ = nullptr;
186 other.previous_ = nullptr;
187 }
188
189 private:
190 // Pointer (not reference) to allow nulling in move constructor
191 const GroupStateHelper* helper_{nullptr};
192 DeferredLogger logger_; // Owned logger
193 DeferredLogger* previous_{nullptr}; // For restore
194 bool do_mpi_gather_{true}; // Whether to gather messages across MPI ranks
195 };
196
198
200 GroupState<Scalar>& group_state,
201 const Schedule& schedule,
202 const SummaryState& summary_state,
203 const GuideRate& guide_rate,
204 const PhaseUsageInfo<IndexTraits>& phase_usage_info,
206 bool terminal_output);
207
208 void accumulateGroupEfficiencyFactor(const Group& group, Scalar& factor) const;
209
210 std::pair<bool, Scalar> checkGroupConstraintsInj(const std::string& name,
211 const std::string& parent,
212 const Group& group,
213 const Scalar* rates,
214 const Phase injection_phase,
215 const Scalar efficiency_factor,
216 const std::vector<Scalar>& resv_coeff,
217 const bool check_guide_rate) const;
218
219 std::pair<bool, Scalar> checkGroupConstraintsProd(const std::string& name,
220 const std::string& parent,
221 const Group& group,
222 const Scalar* rates,
223 const Scalar efficiency_factor,
224 const std::vector<Scalar>& resv_coeff,
225 const bool check_guide_rate) const;
226
227 std::pair<Group::ProductionCMode, Scalar>
228 checkGroupProductionConstraints(const Group& group) const;
229
230 const Parallel::Communication& comm() const { return this->comm_; }
231
235 {
236 if (this->deferred_logger_ == nullptr) {
237 throw std::logic_error("DeferredLogger not set. Call pushLogger() first.");
238 }
239 return *this->deferred_logger_;
240 }
241
242 std::vector<Scalar> getGroupRatesAvailableForHigherLevelControl(const Group& group, const bool is_injector) const;
243
244 Scalar getInjectionGroupTarget(const Group& group,
245 const Phase& injection_phase,
246 const std::vector<Scalar>& resv_coeff) const;
247
251 GuideRateModel::Target getInjectionGuideTargetMode(Phase injection_phase) const;
252
253 Scalar getProductionGroupTarget(const Group& group) const;
254
256 Scalar getProductionGroupTargetForMode(const Group& group,
257 const Group::ProductionCMode cmode) const;
258
262 GuideRateModel::Target getProductionGuideTargetMode(const Group& group) const;
263
264 std::pair<Scalar, Group::ProductionCMode>
265 getAutoChokeGroupProductionTargetRate(const Group& bottom_group,
266 const Group& group,
267 const std::vector<Scalar>& resv_coeff,
268 Scalar efficiencyFactor) const;
269
270 GuideRate::RateVector getProductionGroupRateVector(const std::string& group_name) const;
271
272 std::optional<GroupTarget> getWellGroupTargetInjector(const std::string& name,
273 const std::string& parent,
274 const Group& group,
275 const Scalar* rates,
276 const Phase injection_phase,
277 const Scalar efficiency_factor,
278 const std::vector<Scalar>& resv_coeff) const;
279
280 std::optional<GroupTarget> getWellGroupTargetProducer(const std::string& name,
281 const std::string& parent,
282 const Group& group,
283 const Scalar* rates,
284 const Scalar efficiency_factor,
285 const std::vector<Scalar>& resv_coeff) const;
286
287 GuideRate::RateVector getWellRateVector(const std::string& name) const;
288
289 std::vector<std::string> groupChainTopBot(const std::string& bottom, const std::string& top) const;
290
293 int groupControlledWells(const std::string& group_name,
294 const std::string& always_included_child,
295 const bool is_production_group,
296 const Phase injection_phase) const;
297
299 {
300 return *this->group_state_;
301 }
302
303 const GuideRate& guideRate() const
304 {
305 return this->guide_rate_;
306 }
307
308 bool isRank0() const
309 {
310 return this->well_state_->isRank0();
311 }
312
313 bool isReservoirCouplingMaster() const { return rescoup_.isMaster(); }
314
315 bool isReservoirCouplingMasterGroup(const Group& group) const { return rescoup_.isMasterGroup(group.name()); }
316
317 bool isReservoirCouplingSlave() const { return rescoup_.isSlave(); }
318
319 bool isReservoirCouplingSlaveGroup(const Group& group) const { return rescoup_.isSlaveGroup(group.name()); }
320
321 constexpr int numPhases() const {
322 return this->wellState().numPhases();
323 }
324
325 int phaseToActivePhaseIdx(const Phase phase) const;
326
328 return this->phase_usage_info_;
329 }
330
332 {
333 return GroupStateGuard(*this, group_state);
334 }
335
349 ScopedLoggerGuard pushLogger(bool do_mpi_gather = true) const
350 {
351 return ScopedLoggerGuard(*this, do_mpi_gather);
352 }
353
355 {
356 return WellStateGuard(*this, well_state);
357 }
358
359 int reportStepIdx() const
360 {
361 return report_step_;
362 }
363
364 const Schedule& schedule() const
365 {
366 return this->schedule_;
367 }
368
370 return rescoup_;
371 }
372
374 return rescoup_;
375 }
376
378 return rescoup_.master();
379 }
380
382 return rescoup_.master();
383 }
384
386 return rescoup_.slave();
387 }
389 return rescoup_.slave();
390 }
391
392#ifdef RESERVOIR_COUPLING_ENABLED
393 void setReservoirCouplingMaster(ReservoirCouplingMaster<Scalar>* master) {
394 rescoup_.setMaster(master);
395 }
396 void setReservoirCouplingSlave(ReservoirCouplingSlave<Scalar>* slave) {
397 rescoup_.setSlave(slave);
398 }
399#endif
400
401 void setCmodeGroup(const Group& group);
402
403 template <class AverageRegionalPressureType>
404 void
406 const FieldPropsManager& fp,
407 std::map<std::string, std::unique_ptr<AverageRegionalPressureType>>&
408 regional_average_pressure_calculator) const;
409
410 void setReportStep(int report_step)
411 {
412 report_step_ = report_step;
413 }
414
415 const SummaryState& summaryState() const
416 {
417 return this->summary_state_;
418 }
419
420 Scalar sumSolventRates(const Group& group, const bool is_injector) const;
421
422 Scalar sumWellResRates(const Group& group, const int phase_pos, const bool injector) const;
423
424 Scalar sumWellSurfaceRates(const Group& group, const int phase_pos, const bool injector) const;
425
426 Scalar sumWellPhaseRates(bool res_rates,
427 const Group& group,
428 const int phase_pos,
429 const bool injector,
430 const bool network = false) const;
431
432 bool terminalOutput() const
433 {
434 return this->terminal_output_;
435 }
436
437 template <class RegionalValues>
438 void updateGpMaintTargetForGroups(const Group& group,
439 const RegionalValues& regional_values,
440 const double dt);
441
444 int updateGroupControlledWells(const bool is_production_group,
445 const Phase injection_phase);
446
447 void updateGroupProductionRates(const Group& group);
448
449 void updateGroupTargetReduction(const Group& group,
450 const bool is_injector);
451
453
466
467 void updateREINForGroups(const Group& group, bool sum_rank);
468
469 void updateReservoirRatesInjectionGroups(const Group& group);
470
471#ifdef RESERVOIR_COUPLING_ENABLED
481 void updateSlaveGroupCmodesFromMaster();
482#endif
483
485
486 void updateSurfaceRatesInjectionGroups(const Group& group);
487
488 void updateVREPForGroups(const Group& group);
489
490 void updateWellRates(const Group& group,
491 const WellState<Scalar, IndexTraits>& well_state_nupcol,
492 WellState<Scalar, IndexTraits>& well_state) const;
493
495 {
496 return *this->well_state_;
497 }
498
499 void updateWellRatesFromGroupTargetScale(const Scalar scale,
500 const Group& group,
501 bool is_injector,
502 WellState<Scalar, IndexTraits>& well_state) const;
503
505 std::pair<std::optional<std::string>, Scalar>
506 worstOffendingWell(const Group& group,
507 const Group::ProductionCMode& offended_control) const;
508
509private:
510
532 template<typename ReductionLambda, typename FractionLambda>
533 Scalar applyReductionsAndFractions_(const std::vector<std::string>& chain,
534 Scalar orig_target,
535 Scalar current_rate_available,
536 std::size_t local_reduction_level,
537 bool is_production_group,
538 Phase injection_phase,
539 ReductionLambda&& local_reduction_lambda,
540 FractionLambda&& local_fraction_lambda,
541 bool do_addback) const;
542
543 std::pair<Group::ProductionCMode, Scalar>
544 checkProductionRateConstraint_(const Group& group,
545 Group::ProductionCMode cmode,
546 Group::ProductionCMode currentControl,
547 Scalar target,
548 Scalar current_rate) const;
549
557 std::unordered_set<std::string> collectTargetedProductionGroups_() const;
558
569 Scalar computeAddbackEfficiency_(const std::vector<std::string>& chain,
570 std::size_t local_reduction_level) const;
571
572 std::string controlGroup_(const Group& group) const;
573
574 GuideRate::RateVector getGuideRateVector_(const std::vector<Scalar>& rates) const;
575
576 Scalar getInjectionGroupTargetForMode_(const Group& group,
577 const Phase& injection_phase,
578 const std::vector<Scalar>& resv_coeff,
579 const Group::InjectionCMode cmode) const;
580
591 std::size_t getLocalReductionLevel_(const std::vector<std::string>& chain,
592 bool is_production_group,
593 Phase injection_phase) const;
594
595 Scalar getProductionConstraintTarget_(const Group& group,
596 Group::ProductionCMode cmode,
597 const Group::ProductionControls& controls) const;
598
599 Scalar getProductionGroupTargetForMode_(const Group& group, const Group::ProductionCMode cmode) const;
600
601 Scalar getSatelliteRate_(const Group& group,
602 const int phase_pos,
603 const bool res_rates,
604 const bool is_injector) const;
605
609 bool isAutoChokeGroupUnderperforming_(const Group& group) const;
610
612 bool isInGroupChainTopBot_(const std::string& bottom, const std::string& top) const;
613
614 bool isSatelliteGroup_(const Group& group) const;
615
616 Scalar satelliteInjectionRate_(const ScheduleState& sched,
617 const Group& group,
618 const int phase_pos,
619 bool res_rates) const;
620
621 Scalar satelliteProductionRate_(const ScheduleState& sched,
622 const Group& group,
623 const GSatProd::GSatProdGroupProp::Rate rate_comp,
624 bool res_rates) const;
625
626 std::optional<GSatProd::GSatProdGroupProp::Rate> selectRateComponent_(const int phase_pos) const;
627
638 Scalar subtractOtherPhaseResvInjection_(
639 Phase injection_phase,
640 Scalar base_reservoir_rate,
641 const std::vector<Scalar>& group_injection_reservoir_rates) const;
642
643 Scalar sumProductionRateForControlMode_(const Group& group, Group::ProductionCMode cmode) const;
644
645 int updateGroupControlledWellsRecursive_(const std::string& group_name,
646 const bool is_production_group,
647 const Phase injection_phase);
648
649 void updateGroupTargetReductionRecursive_(const Group& group,
650 const bool is_injector,
651 std::vector<Scalar>& group_target_reduction);
652
653 // Validate that GCONINJE top-up phases (RESV/VREP) are consistent
654 // across the group hierarchy. Called once from setCmodeGroup() for FIELD.
655 void validateInjectionTopupPhases_(const Group& group) const;
656
657 // Recursive helper for validateInjectionTopupPhases_()
658 void validateInjectionTopupPhasesRecursive_(const Group& group,
659 std::optional<Phase> inherited_topup_phase,
660 const std::string& inherited_topup_group) const;
661
662 // --- Reservoir coupling private methods ---
663#ifdef RESERVOIR_COUPLING_ENABLED
668 ReservoirCoupling::Phase activePhaseIdxToRescoupPhase_(int phase_pos) const;
669
678 std::unordered_set<std::string> collectMasterGroupHierarchy_() const;
679
693 Scalar getEffectiveProductionLimit_(const std::string& gname,
694 Group::ProductionCMode rate_type,
695 Scalar slave_local_target) const;
696
697 ReservoirCoupling::GrupSlav::FilterFlag getInjectionFilterFlag_(const std::string& group_name,
698 const Phase injection_phase) const;
699
700 ReservoirCoupling::GrupSlav::FilterFlag getProductionFilterFlag_(const std::string& group_name,
701 const Group::ProductionCMode cmode) const;
702
703 Scalar getReservoirCouplingMasterGroupRate_(const Group& group,
704 const int phase_pos,
705 const ReservoirCoupling::RateKind kind) const;
706#endif // RESERVOIR_COUPLING_ENABLED
707
708 const WellState<Scalar, IndexTraits>* well_state_ {nullptr};
709 GroupState<Scalar>* group_state_ {nullptr};
710 const Schedule& schedule_;
711 const SummaryState& summary_state_;
712 const GuideRate& guide_rate_;
713 // NOTE: The deferred logger does not change the object "meaningful" state, so it should be ok to
714 // make it mutable and store a pointer to it here.
715 mutable DeferredLogger* deferred_logger_ {nullptr};
716 // NOTE: The phase usage info seems to be read-only throughout the simulation, so it should be safe
717 // to store a reference to it here.
718 const PhaseUsageInfo<IndexTraits>& phase_usage_info_;
719 const Parallel::Communication& comm_;
720 bool terminal_output_ {false};
721 int report_step_ {0};
722 ReservoirCoupling::Proxy<Scalar> rescoup_{};
723};
724
725// -----------------------------------------------------------------------------
726// Template member function implementations
727// -----------------------------------------------------------------------------
728
729// NOTE: This template member function is defined here in the header because the
730// AverageRegionalPressureType type parameter depends on derived class types that are
731// not available when GroupStateHelper.cpp is compiled. Template functions
732// must be visible at their instantiation point.
733// See GroupStateHelper.cpp for detailed rationale.
734template <typename Scalar, typename IndexTraits>
735template <class AverageRegionalPressureType>
736void
738 const Group& group,
739 const FieldPropsManager& fp,
740 std::map<std::string, std::unique_ptr<AverageRegionalPressureType>>& regional_average_pressure_calculator)
741 const
742{
743 for (const std::string& groupName : group.groups()) {
744 this->setRegionAveragePressureCalculator(this->schedule_.getGroup(groupName, this->report_step_),
745 fp,
746 regional_average_pressure_calculator);
747 }
748 const auto& gpm = group.gpmaint();
749 if (!gpm)
750 return;
751
752 const auto& reg = gpm->region();
753 if (!reg)
754 return;
755
756 if (regional_average_pressure_calculator.count(reg->first) == 0) {
757 const std::string name = (reg->first.rfind("FIP", 0) == 0) ? reg->first : "FIP" + reg->first;
758 const auto& fipnum = fp.get_int(name);
759 regional_average_pressure_calculator[reg->first]
760 = std::make_unique<AverageRegionalPressureType>(fipnum);
761 }
762}
763
764// NOTE: This template member function is defined in the header because the
765// RegionalValues type parameter depends on derived class types that are
766// not available when GroupStateHelper.cpp is compiled. Template functions
767// must be visible at their instantiation point.
768// See GroupStateHelper.cpp for detailed rationale.
769template <typename Scalar, typename IndexTraits>
770template <class RegionalValues>
771void
773 const RegionalValues& regional_values,
774 const double dt)
775{
776 OPM_TIMEFUNCTION();
777 for (const std::string& group_name : group.groups()) {
778 const Group& group_tmp = this->schedule_.getGroup(group_name, this->report_step_);
779 this->updateGpMaintTargetForGroups(group_tmp, regional_values, dt);
780 }
781 const auto& gpm = group.gpmaint();
782 if (!gpm)
783 return;
784
785 const auto& region = gpm->region();
786 if (!region)
787 return;
788 if (this->isReservoirCouplingMasterGroup(group)) {
789 // GPMAINT is not supported for reservoir coupling master groups since master groups do not have
790 // subordinate wells in the master reservoir, so the slaves cannot influence the master reservoir's
791 // average pressure.
792 // Even specifying GPMAINT on a group superior to the master group might not make sense, since if the
793 // superior target is distributed down to the master group with guide rate fractions, adjusting
794 // the master group's target (that is sent to the slave) could only indirectly influence the master
795 // reservoir's average pressure by affecting the guide rate fractions distributed to actual wells
796 // in the master reservoir.
798 std::runtime_error,
799 "GPMAINT is not supported for reservoir coupling master groups.",
800 this->deferredLogger()
801 );
802 return;
803 }
804 else if (this->isReservoirCouplingSlaveGroup(group)) {
805 // GPMAINT is not supported for reservoir coupling slave groups since their targets will be overridden
806 // by the corresponding master group's target anyway.
808 std::runtime_error,
809 "GPMAINT is not supported for reservoir coupling slave groups.",
810 this->deferredLogger()
811 );
812 return;
813 }
814 const auto [name, number] = *region;
815 const Scalar error = gpm->pressure_target() - regional_values.at(name)->pressure(number);
816 Scalar current_rate = 0.0;
817 const auto& pu = this->phase_usage_info_;
818 bool injection = true;
819 Scalar sign = 1.0;
820 switch (gpm->flow_target()) {
821 case GPMaint::FlowTarget::RESV_PROD: {
822 current_rate = -this->groupState().injection_vrep_rate(group.name());
823 injection = false;
824 sign = -1.0;
825 break;
826 }
827 case GPMaint::FlowTarget::RESV_OINJ: {
828 if (pu.phaseIsActive(IndexTraits::oilPhaseIdx)) {
829 const auto io = pu.canonicalToActivePhaseIdx(IndexTraits::oilPhaseIdx);
830 current_rate = this->groupState().injection_reservoir_rates(group.name())[io];
831 }
832 break;
833 }
834 case GPMaint::FlowTarget::RESV_WINJ: {
835 if (pu.phaseIsActive(IndexTraits::waterPhaseIdx)) {
836 const auto iw = pu.canonicalToActivePhaseIdx(IndexTraits::waterPhaseIdx);
837 current_rate = this->groupState().injection_reservoir_rates(group.name())[iw];
838 }
839 break;
840 }
841 case GPMaint::FlowTarget::RESV_GINJ: {
842 if (pu.phaseIsActive(IndexTraits::gasPhaseIdx)) {
843 const auto ig = pu.canonicalToActivePhaseIdx(IndexTraits::gasPhaseIdx);
844 current_rate = this->groupState().injection_reservoir_rates(group.name())[ig];
845 }
846 break;
847 }
848 case GPMaint::FlowTarget::SURF_OINJ: {
849 if (pu.phaseIsActive(IndexTraits::oilPhaseIdx)) {
850 const auto io = pu.canonicalToActivePhaseIdx(IndexTraits::oilPhaseIdx);
851 current_rate = this->groupState().injection_surface_rates(group.name())[io];
852 }
853 break;
854 }
855 case GPMaint::FlowTarget::SURF_WINJ: {
856 if (pu.phaseIsActive(IndexTraits::waterPhaseIdx)) {
857 const auto iw = pu.canonicalToActivePhaseIdx(IndexTraits::waterPhaseIdx);
858 current_rate = this->groupState().injection_surface_rates(group.name())[iw];
859 }
860 break;
861 }
862 case GPMaint::FlowTarget::SURF_GINJ: {
863 if (pu.phaseIsActive(IndexTraits::gasPhaseIdx)) {
864 const auto ig = pu.canonicalToActivePhaseIdx(IndexTraits::gasPhaseIdx);
865 current_rate = this->groupState().injection_surface_rates(group.name())[ig];
866 }
867 break;
868 }
869 default:
870 throw std::invalid_argument("Invalid Flow target type in GPMAINT");
871 }
872 auto& gpmaint_state = this->groupState().gpmaint(group.name());
873 // we only activate gpmaint if pressure is lower than the target regional pressure for injectors
874 // (i.e. error > 0) and higher for producers.
875 bool activate = (injection && error > 0) || (!injection && error < 0);
876 Scalar rate = 0.0;
877 if (activate) {
878 rate = gpm->rate(gpmaint_state, current_rate, error, dt);
879 } else {
880 gpm->resetState(gpmaint_state);
881 }
882 this->groupState().update_gpmaint_target(group.name(), std::max(Scalar {0.0}, sign * rate));
883}
884
885} // namespace Opm
886
887#endif // OPM_GROUPSTATE_HELPER_HEADER_INCLUDED
#define OPM_DEFLOG_THROW(Exception, message, deferred_logger)
Definition: DeferredLoggingErrorHelpers.hpp:45
Definition: DeferredLogger.hpp:57
Definition: GroupStateHelper.hpp:90
GroupStateGuard(GroupStateGuard &&)=delete
GroupStateGuard & operator=(GroupStateGuard &&)=delete
GroupStateGuard(GroupStateHelper &group_state_helper, GroupState< Scalar > &group_state)
Definition: GroupStateHelper.hpp:92
GroupStateGuard(const GroupStateGuard &)=delete
~GroupStateGuard()
Definition: GroupStateHelper.hpp:100
GroupStateGuard & operator=(const GroupStateGuard &)=delete
RAII guard that owns a DeferredLogger and auto-gathers on destruction.
Definition: GroupStateHelper.hpp:130
ScopedLoggerGuard & operator=(const ScopedLoggerGuard &)=delete
ScopedLoggerGuard(ScopedLoggerGuard &&other) noexcept
Definition: GroupStateHelper.hpp:175
ScopedLoggerGuard(const ScopedLoggerGuard &)=delete
ScopedLoggerGuard(const GroupStateHelper &helper, bool do_mpi_gather=true)
Constructor for scoped logger guard.
Definition: GroupStateHelper.hpp:137
~ScopedLoggerGuard()
Definition: GroupStateHelper.hpp:145
ScopedLoggerGuard & operator=(ScopedLoggerGuard &&)=delete
Definition: GroupStateHelper.hpp:61
WellStateGuard(WellStateGuard &&)=delete
WellStateGuard(const WellStateGuard &)=delete
~WellStateGuard()
Definition: GroupStateHelper.hpp:71
WellStateGuard & operator=(const WellStateGuard &)=delete
WellStateGuard & operator=(WellStateGuard &&)=delete
WellStateGuard(GroupStateHelper &groupStateHelper, WellState< Scalar, IndexTraits > &well_state)
Definition: GroupStateHelper.hpp:63
Definition: GroupStateHelper.hpp:57
void updateWellRatesFromGroupTargetScale(const Scalar scale, const Group &group, bool is_injector, WellState< Scalar, IndexTraits > &well_state) const
std::pair< Scalar, Group::ProductionCMode > getAutoChokeGroupProductionTargetRate(const Group &bottom_group, const Group &group, const std::vector< Scalar > &resv_coeff, Scalar efficiencyFactor) const
void setRegionAveragePressureCalculator(const Group &group, const FieldPropsManager &fp, std::map< std::string, std::unique_ptr< AverageRegionalPressureType > > &regional_average_pressure_calculator) const
Definition: GroupStateHelper.hpp:737
void setCmodeGroup(const Group &group)
std::vector< std::string > groupChainTopBot(const std::string &bottom, const std::string &top) const
void updateVREPForGroups(const Group &group)
void updateWellRates(const Group &group, const WellState< Scalar, IndexTraits > &well_state_nupcol, WellState< Scalar, IndexTraits > &well_state) const
std::optional< GroupTarget > getWellGroupTargetProducer(const std::string &name, const std::string &parent, const Group &group, const Scalar *rates, const Scalar efficiency_factor, const std::vector< Scalar > &resv_coeff) const
ReservoirCouplingMaster< Scalar > & reservoirCouplingMaster()
Definition: GroupStateHelper.hpp:377
GroupState< Scalar > & groupState() const
Definition: GroupStateHelper.hpp:298
Scalar sumWellResRates(const Group &group, const int phase_pos, const bool injector) const
void accumulateGroupEfficiencyFactor(const Group &group, Scalar &factor) const
int groupControlledWells(const std::string &group_name, const std::string &always_included_child, const bool is_production_group, const Phase injection_phase) const
const PhaseUsageInfo< IndexTraits > & phaseUsage() const
Definition: GroupStateHelper.hpp:327
const ReservoirCouplingMaster< Scalar > & reservoirCouplingMaster() const
Definition: GroupStateHelper.hpp:381
const SummaryState & summaryState() const
Definition: GroupStateHelper.hpp:415
const GuideRate & guideRate() const
Definition: GroupStateHelper.hpp:303
std::pair< std::optional< std::string >, Scalar > worstOffendingWell(const Group &group, const Group::ProductionCMode &offended_control) const
Returns the name of the worst offending well and its fraction (i.e. violated_phase / preferred_phase)
ReservoirCoupling::Proxy< Scalar > & rescoup()
Definition: GroupStateHelper.hpp:369
void updateReservoirRatesInjectionGroups(const Group &group)
bool isReservoirCouplingSlaveGroup(const Group &group) const
Definition: GroupStateHelper.hpp:319
const WellState< Scalar, IndexTraits > & wellState() const
Definition: GroupStateHelper.hpp:494
constexpr int numPhases() const
Definition: GroupStateHelper.hpp:321
GuideRate::RateVector getWellRateVector(const std::string &name) const
ScopedLoggerGuard pushLogger(bool do_mpi_gather=true) const
Push a new logger onto the stack with auto-cleanup on destruction.
Definition: GroupStateHelper.hpp:349
const Parallel::Communication & comm() const
Definition: GroupStateHelper.hpp:230
GuideRateModel::Target getInjectionGuideTargetMode(Phase injection_phase) const
Get the guide rate target mode for an injection phase.
bool isRank0() const
Definition: GroupStateHelper.hpp:308
std::pair< Group::ProductionCMode, Scalar > checkGroupProductionConstraints(const Group &group) const
Scalar sumSolventRates(const Group &group, const bool is_injector) const
const Schedule & schedule() const
Definition: GroupStateHelper.hpp:364
void updateGroupTargetReduction(const Group &group, const bool is_injector)
GuideRate::RateVector getProductionGroupRateVector(const std::string &group_name) const
void updateGroupProductionRates(const Group &group)
bool terminalOutput() const
Definition: GroupStateHelper.hpp:432
typename SingleWellState< Scalar, IndexTraits >::GroupTarget GroupTarget
Definition: GroupStateHelper.hpp:197
void updateGpMaintTargetForGroups(const Group &group, const RegionalValues &regional_values, const double dt)
Definition: GroupStateHelper.hpp:772
int phaseToActivePhaseIdx(const Phase phase) const
std::pair< bool, Scalar > checkGroupConstraintsProd(const std::string &name, const std::string &parent, const Group &group, const Scalar *rates, const Scalar efficiency_factor, const std::vector< Scalar > &resv_coeff, const bool check_guide_rate) const
DeferredLogger & deferredLogger() const
Get the deferred logger.
Definition: GroupStateHelper.hpp:234
Scalar sumWellSurfaceRates(const Group &group, const int phase_pos, const bool injector) const
int reportStepIdx() const
Definition: GroupStateHelper.hpp:359
void setReportStep(int report_step)
Definition: GroupStateHelper.hpp:410
int updateGroupControlledWells(const bool is_production_group, const Phase injection_phase)
void updateState(WellState< Scalar, IndexTraits > &well_state, GroupState< Scalar > &group_state)
std::vector< Scalar > getGroupRatesAvailableForHigherLevelControl(const Group &group, const bool is_injector) const
bool isReservoirCouplingMasterGroup(const Group &group) const
Definition: GroupStateHelper.hpp:315
const ReservoirCoupling::Proxy< Scalar > & rescoup() const
Definition: GroupStateHelper.hpp:373
bool isReservoirCouplingMaster() const
Definition: GroupStateHelper.hpp:313
const ReservoirCouplingSlave< Scalar > & reservoirCouplingSlave() const
Definition: GroupStateHelper.hpp:388
void updateNetworkLeafNodeProductionRates()
Scalar getProductionGroupTargetForMode(const Group &group, const Group::ProductionCMode cmode) const
Get the production target for a specific control mode (not necessarily the active one).
WellStateGuard pushWellState(WellState< Scalar, IndexTraits > &well_state)
Definition: GroupStateHelper.hpp:354
Scalar getInjectionGroupTarget(const Group &group, const Phase &injection_phase, const std::vector< Scalar > &resv_coeff) const
GroupStateGuard pushGroupState(GroupState< Scalar > &group_state)
Definition: GroupStateHelper.hpp:331
ReservoirCouplingSlave< Scalar > & reservoirCouplingSlave()
Definition: GroupStateHelper.hpp:385
Scalar sumWellPhaseRates(bool res_rates, const Group &group, const int phase_pos, const bool injector, const bool network=false) const
void updateREINForGroups(const Group &group, bool sum_rank)
bool isReservoirCouplingSlave() const
Definition: GroupStateHelper.hpp:317
GuideRateModel::Target getProductionGuideTargetMode(const Group &group) const
Get the guide rate target mode for a production group.
void updateNONEProductionGroups()
Set production control to NONE for groups not targeting any well.
Scalar getProductionGroupTarget(const Group &group) const
std::pair< bool, Scalar > checkGroupConstraintsInj(const std::string &name, const std::string &parent, const Group &group, const Scalar *rates, const Phase injection_phase, const Scalar efficiency_factor, const std::vector< Scalar > &resv_coeff, const bool check_guide_rate) const
std::optional< GroupTarget > getWellGroupTargetInjector(const std::string &name, const std::string &parent, const Group &group, const Scalar *rates, const Phase injection_phase, const Scalar efficiency_factor, const std::vector< Scalar > &resv_coeff) const
GroupStateHelper(WellState< Scalar, IndexTraits > &well_state, GroupState< Scalar > &group_state, const Schedule &schedule, const SummaryState &summary_state, const GuideRate &guide_rate, const PhaseUsageInfo< IndexTraits > &phase_usage_info, const Parallel::Communication &comm, bool terminal_output)
void updateSurfaceRatesInjectionGroups(const Group &group)
Definition: GroupState.hpp:41
Definition: GasLiftGroupInfo.hpp:38
Thin proxy for reservoir coupling master/slave pointers.
Definition: RescoupProxy.hpp:54
Definition: ReservoirCouplingMaster.hpp:38
Definition: ReservoirCouplingSlave.hpp:40
Definition: WellState.hpp:66
Dune::Communication< MPIComm > Communication
Definition: ParallelCommunication.hpp:30
RateKind
Selects which kind of rate to retrieve from slave group data.
Definition: ReservoirCoupling.hpp:168
Phase
Phase indices for reservoir coupling, we currently only support black-oil phases (oil,...
Definition: ReservoirCoupling.hpp:156
Definition: blackoilbioeffectsmodules.hh:45
Opm::DeferredLogger gatherDeferredLogger(const Opm::DeferredLogger &local_deferredlogger, Parallel::Communication communicator)
Create a global log combining local logs.
Definition: SingleWellState.hpp:121