My Project
Well.hpp
1/*
2 Copyright 2019 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
21#ifndef WELL2_HPP
22#define WELL2_HPP
23
24#include <cstddef>
25#include <iosfwd>
26#include <map>
27#include <memory>
28#include <optional>
29#include <string>
30#include <utility>
31#include <vector>
32
33#include <opm/input/eclipse/Deck/UDAValue.hpp>
34#include <opm/input/eclipse/EclipseState/Phase.hpp>
35#include <opm/input/eclipse/Schedule/ScheduleTypes.hpp>
36#include <opm/input/eclipse/Schedule/VFPProdTable.hpp>
37#include <opm/input/eclipse/Schedule/Well/PAvg.hpp>
38#include <opm/input/eclipse/Schedule/Well/PAvgCalculator.hpp>
39#include <opm/input/eclipse/Schedule/Well/WellEnums.hpp>
40#include <opm/input/eclipse/Schedule/Well/WellInjectionControls.hpp>
41#include <opm/input/eclipse/Schedule/Well/WellProductionControls.hpp>
42#include <opm/input/eclipse/Units/UnitSystem.hpp>
43
44namespace Opm {
45
46class ActiveGridCells;
47class AutoICD;
48class DeckKeyword;
49class DeckRecord;
50class ErrorGuard;
51class EclipseGrid;
52class ParseContext;
53class ScheduleGrid;
54class SICD;
55class SummaryState;
56class UDQActive;
57class UDQConfig;
58class Valve;
59class TracerConfig;
60class WellConnections;
61struct WellBrineProperties;
62class WellEconProductionLimits;
63struct WellFoamProperties;
64struct WellMICPProperties;
65struct WellPolymerProperties;
66class WellSegments;
67class WellTracerProperties;
68class WVFPEXP;
69
70namespace RestartIO {
71struct RstWell;
72}
73
74class Well {
75public:
76 using Status = WellStatus;
77
78 /*
79 The elements in this enum are used as bitmasks to keep track
80 of which controls are present, i.e. the 2^n structure must
81 be intact.
82 */
83 using InjectorCMode = WellInjectorCMode;
84
85 /*
86 The properties are initialized with the CMODE_UNDEFINED
87 value, but the undefined value is never assigned apart from
88 that; and it is not part of the string conversion routines.
89 */
90 using ProducerCMode = WellProducerCMode;
91
92 using WELTARGCMode = WellWELTARGCMode;
93
94 using GuideRateTarget = WellGuideRateTarget;
95
96 using GasInflowEquation = WellGasInflowEquation;
97
99 bool available;
100 double guide_rate;
101 GuideRateTarget guide_phase;
102 double scale_factor;
103
104 static WellGuideRate serializationTestObject()
105 {
106 WellGuideRate result;
107 result.available = true;
108 result.guide_rate = 1.0;
109 result.guide_phase = GuideRateTarget::COMB;
110 result.scale_factor = 2.0;
111
112 return result;
113 }
114
115 bool operator==(const WellGuideRate& data) const {
116 return available == data.available &&
117 guide_rate == data.guide_rate &&
118 guide_phase == data.guide_phase &&
119 scale_factor == data.scale_factor;
120 }
121
122 template<class Serializer>
123 void serializeOp(Serializer& serializer)
124 {
125 serializer(available);
126 serializer(guide_rate);
127 serializer(guide_phase);
128 serializer(scale_factor);
129 }
130 };
131
133
135 std::string name;
136 UDAValue surfaceInjectionRate;
137 UDAValue reservoirInjectionRate;
138 UDAValue BHPTarget;
139 UDAValue THPTarget;
140
141 double bhp_hist_limit = 0.0;
142 double thp_hist_limit = 0.0;
143
144 double BHPH;
145 double THPH;
146 int VFPTableNumber;
147 bool predictionMode;
148 int injectionControls;
149 InjectorType injectorType;
150 InjectorCMode controlMode;
151
152 double rsRvInj;
153
154 bool operator==(const WellInjectionProperties& other) const;
155 bool operator!=(const WellInjectionProperties& other) const;
156
158 WellInjectionProperties(const UnitSystem& units, const std::string& wname);
159
160 static WellInjectionProperties serializationTestObject();
161
162 void handleWELTARG(WELTARGCMode cmode, const UDAValue& new_arg, double SIFactorP);
163 void handleWCONINJE(const DeckRecord& record, bool availableForGroupControl, const std::string& well_name);
164 void handleWCONINJH(const DeckRecord& record, bool is_producer, const std::string& well_name);
165 bool hasInjectionControl(InjectorCMode controlModeArg) const {
166 if (injectionControls & static_cast<int>(controlModeArg))
167 return true;
168 else
169 return false;
170 }
171
172 void dropInjectionControl(InjectorCMode controlModeArg) {
173 auto int_arg = static_cast<int>(controlModeArg);
174 if ((injectionControls & int_arg) != 0)
175 injectionControls -= int_arg;
176 }
177
178 void addInjectionControl(InjectorCMode controlModeArg) {
179 auto int_arg = static_cast<int>(controlModeArg);
180 if ((injectionControls & int_arg) == 0)
181 injectionControls += int_arg;
182 }
183
184 void clearControls();
185
186 void resetDefaultHistoricalBHPLimit();
187 void resetBHPLimit();
188 void setBHPLimit(const double limit);
189 InjectionControls controls(const UnitSystem& unit_system, const SummaryState& st, double udq_default) const;
190 bool updateUDQActive(const UDQConfig& udq_config, UDQActive& active) const;
191 bool updateUDQActive(const UDQConfig& udq_config, const WELTARGCMode cmode, UDQActive& active) const;
192 void update_uda(const UDQConfig& udq_config, UDQActive& udq_active, UDAControl control, const UDAValue& value);
193 void handleWTMULT(Well::WELTARGCMode cmode, double factor);
194
195 template<class Serializer>
196 void serializeOp(Serializer& serializer)
197 {
198 serializer(name);
199 serializer(surfaceInjectionRate);
200 serializer(reservoirInjectionRate);
201 serializer(BHPTarget);
202 serializer(THPTarget);
203 serializer(bhp_hist_limit);
204 serializer(thp_hist_limit);
205 serializer(BHPH);
206 serializer(THPH);
207 serializer(VFPTableNumber);
208 serializer(predictionMode);
209 serializer(injectionControls);
210 serializer(injectorType);
211 serializer(controlMode);
212 serializer(rsRvInj);
213 }
214 };
215
217
219 public:
220 // the rates serve as limits under prediction mode
221 // while they are observed rates under historical mode
222 std::string name;
223 UDAValue OilRate;
224 UDAValue WaterRate;
225 UDAValue GasRate;
226 UDAValue LiquidRate;
227 UDAValue ResVRate;
228 UDAValue BHPTarget;
229 UDAValue THPTarget;
230 UDAValue ALQValue;
231
232 // BHP and THP limit
233 double bhp_hist_limit = 0.0;
234 double thp_hist_limit = 0.0;
235
236 // historical BHP and THP under historical mode
237 double BHPH = 0.0;
238 double THPH = 0.0;
239 int VFPTableNumber = 0;
240 bool predictionMode = false;
241 ProducerCMode controlMode = ProducerCMode::CMODE_UNDEFINED;
242 ProducerCMode whistctl_cmode = ProducerCMode::CMODE_UNDEFINED;
243
244 bool operator==(const WellProductionProperties& other) const;
245 bool operator!=(const WellProductionProperties& other) const;
246
248 WellProductionProperties(const UnitSystem& units, const std::string& name_arg);
249
250 static WellProductionProperties serializationTestObject();
251
252 bool hasProductionControl(ProducerCMode controlModeArg) const {
253 return (m_productionControls & static_cast<int>(controlModeArg)) != 0;
254 }
255
256 void dropProductionControl(ProducerCMode controlModeArg) {
257 if (hasProductionControl(controlModeArg))
258 m_productionControls -= static_cast<int>(controlModeArg);
259 }
260
261 void addProductionControl(ProducerCMode controlModeArg) {
262 if (! hasProductionControl(controlModeArg))
263 m_productionControls += static_cast<int>(controlModeArg);
264 }
265
266 // this is used to check whether the specified control mode is an effective history matching production mode
267 static bool effectiveHistoryProductionControl(ProducerCMode cmode);
268 void handleWCONPROD( const std::optional<VFPProdTable::ALQ_TYPE>& alq_type, const UnitSystem& unit_system, const std::string& well, const DeckRecord& record);
269 void handleWCONHIST( const std::optional<VFPProdTable::ALQ_TYPE>& alq_type, const UnitSystem& unit_system, const DeckRecord& record);
270 void handleWELTARG( WELTARGCMode cmode, const UDAValue& new_arg, double SiFactorP);
271 void resetDefaultBHPLimit();
272 void clearControls();
273 ProductionControls controls(const SummaryState& st, double udq_default) const;
274 bool updateUDQActive(const UDQConfig& udq_config, UDQActive& active) const;
275 bool updateUDQActive(const UDQConfig& udq_config, const WELTARGCMode cmode, UDQActive& active) const;
276 void update_uda(const UDQConfig& udq_config, UDQActive& udq_active, UDAControl control, const UDAValue& value);
277
278 void setBHPLimit(const double limit);
279 int productionControls() const { return this->m_productionControls; }
280 void handleWTMULT(Well::WELTARGCMode cmode, double factor);
281
282 template<class Serializer>
283 void serializeOp(Serializer& serializer)
284 {
285 serializer(name);
286 serializer(OilRate);
287 serializer(WaterRate);
288 serializer(GasRate);
289 serializer(LiquidRate);
290 serializer(ResVRate);
291 serializer(BHPTarget);
292 serializer(THPTarget);
293 serializer(ALQValue);
294 serializer(bhp_hist_limit);
295 serializer(thp_hist_limit);
296 serializer(BHPH);
297 serializer(THPH);
298 serializer(VFPTableNumber);
299 serializer(predictionMode);
300 serializer(controlMode);
301 serializer(whistctl_cmode);
302 serializer(m_productionControls);
303 }
304
305 private:
306 int m_productionControls = 0;
307 void init_rates( const DeckRecord& record );
308
309 void init_history(const DeckRecord& record);
310 void init_vfp(const std::optional<VFPProdTable::ALQ_TYPE>& alq_type, const UnitSystem& unit_system, const DeckRecord& record);
311
313
314 double getBHPLimit() const;
315 };
316
317 static int eclipseControlMode(const Well::InjectorCMode imode,
318 const InjectorType itype);
319
320 static int eclipseControlMode(const Well::ProducerCMode pmode);
321
322 static int eclipseControlMode(const Well& well,
323 const SummaryState& st);
324
325
326 Well() = default;
327 Well(const std::string& wname,
328 const std::string& gname,
329 std::size_t init_step,
330 std::size_t insert_index,
331 int headI,
332 int headJ,
333 const std::optional<double>& ref_depth,
334 const WellType& wtype_arg,
335 ProducerCMode whistctl_cmode,
336 Connection::Order ordering,
337 const UnitSystem& unit_system,
338 double udq_undefined,
339 double dr,
340 bool allow_xflow,
341 bool auto_shutin,
342 int pvt_table,
343 GasInflowEquation inflow_eq);
344
345 Well(const RestartIO::RstWell& rst_well,
346 int report_step,
347 const TracerConfig& tracer_config,
348 const UnitSystem& unit_system,
349 double udq_undefined);
350
351 static Well serializationTestObject();
352
353 bool isMultiSegment() const;
354 bool isAvailableForGroupControl() const;
355 double getGuideRate() const;
356 GuideRateTarget getGuideRatePhase() const;
357 GuideRateTarget getRawGuideRatePhase() const;
358 double getGuideRateScalingFactor() const;
359
360 bool hasBeenDefined(std::size_t timeStep) const;
361 std::size_t firstTimeStep() const;
362 const WellType& wellType() const;
363 bool predictionMode() const;
364 bool canOpen() const;
365 bool isProducer() const;
366 bool isInjector() const;
367 InjectorCMode injection_cmode() const;
368 ProducerCMode production_cmode() const;
369 InjectorType injectorType() const;
370 std::size_t seqIndex() const;
371 bool getAutomaticShutIn() const;
372 bool getAllowCrossFlow() const;
373 const std::string& name() const;
374 const std::vector<std::string>& wListNames() const;
375 int getHeadI() const;
376 int getHeadJ() const;
377 double getWPaveRefDepth() const;
378 bool hasRefDepth() const;
379 double getRefDepth() const;
380 double getDrainageRadius() const;
381 double getEfficiencyFactor() const;
382 double getSolventFraction() const;
383 Status getStatus() const;
384 const std::string& groupName() const;
385 Phase getPreferredPhase() const;
386
387 bool hasConnections() const;
388 const std::vector<const Connection *> getConnections(int completion) const;
389 const WellConnections& getConnections() const;
390 const WellSegments& getSegments() const;
391
392 const WellProductionProperties& getProductionProperties() const;
393 const WellInjectionProperties& getInjectionProperties() const;
394 const WellEconProductionLimits& getEconLimits() const;
395 const WellFoamProperties& getFoamProperties() const;
396 const WellPolymerProperties& getPolymerProperties() const;
397 const WellMICPProperties& getMICPProperties() const;
398 const WellBrineProperties& getBrineProperties() const;
399 const WellTracerProperties& getTracerProperties() const;
400 const WVFPEXP& getWVFPEXP() const;
401 /* The rate of a given phase under the following assumptions:
402 * * Returns zero if production is requested for an injector (and vice
403 * versa)
404 * * If this is an injector and something else than the
405 * requested phase is injected, returns 0, i.e.
406 * water_injector.injection_rate( gas ) == 0
407 * * Mixed injection is not supported and always returns 0.
408 */
409 double production_rate( const SummaryState& st, Phase phase) const;
410 double injection_rate( const SummaryState& st, Phase phase) const;
411 static bool wellNameInWellNamePattern(const std::string& wellName, const std::string& wellNamePattern);
412
413 /*
414 The getCompletions() function will return a map:
415
416 {
417 1 : [Connection, Connection],
418 2 : [Connection, Connection, Connecton],
419 3 : [Connection],
420 4 : [Connection]
421 }
422
423 The integer ID's correspond to the COMPLETION id given by the COMPLUMP
424 keyword.
425 */
426 std::map<int, std::vector<Connection>> getCompletions() const;
427 /*
428 For hasCompletion(int completion) and getConnections(int completion) the
429 completion argument is an integer ID used to denote a collection of
430 connections. The integer ID is assigned with the COMPLUMP keyword.
431 */
432 bool hasCompletion(int completion) const;
433 bool updatePrediction(bool prediction_mode);
434 bool updateAutoShutin(bool auto_shutin);
435 bool updateCrossFlow(bool allow_cross_flow);
436 bool updatePVTTable(int pvt_table);
437 bool updateHead(int I, int J);
438 void updateRefDepth();
439 bool updateRefDepth(const std::optional<double>& ref_dpeth);
440 bool updateDrainageRadius(double drainage_radius);
441 void updateSegments(std::shared_ptr<WellSegments> segments_arg);
442 bool updateConnections(std::shared_ptr<WellConnections> connections, bool force);
443 bool updateConnections(std::shared_ptr<WellConnections> connections, const ScheduleGrid& grid);
444 bool updateStatus(Status status);
445 bool updateGroup(const std::string& group);
446 bool updateWellGuideRate(bool available, double guide_rate, GuideRateTarget guide_phase, double scale_factor);
447 bool updateWellGuideRate(double guide_rate);
448 bool updateEfficiencyFactor(double efficiency_factor);
449 bool updateSolventFraction(double solvent_fraction);
450 bool updateTracer(std::shared_ptr<WellTracerProperties> tracer_properties);
451 bool updateFoamProperties(std::shared_ptr<WellFoamProperties> foam_properties);
452 bool updatePolymerProperties(std::shared_ptr<WellPolymerProperties> polymer_properties);
453 bool updateMICPProperties(std::shared_ptr<WellMICPProperties> micp_properties);
454 bool updateBrineProperties(std::shared_ptr<WellBrineProperties> brine_properties);
455 bool updateEconLimits(std::shared_ptr<WellEconProductionLimits> econ_limits);
456 bool updateProduction(std::shared_ptr<WellProductionProperties> production);
457 bool updateInjection(std::shared_ptr<WellInjectionProperties> injection);
458 bool updateWellProductivityIndex();
459 bool updateWSEGSICD(const std::vector<std::pair<int, SICD> >& sicd_pairs);
460 bool updateWSEGVALV(const std::vector<std::pair<int, Valve> >& valve_pairs);
461 bool updateWSEGAICD(const std::vector<std::pair<int, AutoICD> >& aicd_pairs, const KeywordLocation& location);
462 bool updateWPAVE(const PAvg& pavg);
463 void updateWPaveRefDepth(double ref_depth);
464 bool updateWVFPEXP(std::shared_ptr<WVFPEXP> wvfpexp);
465
466 bool handleWELSEGS(const DeckKeyword& keyword);
467 bool handleCOMPSEGS(const DeckKeyword& keyword, const ScheduleGrid& grid, const ParseContext& parseContext, ErrorGuard& errors);
468 bool handleWELOPENConnections(const DeckRecord& record, Connection::State status);
469 bool handleCOMPLUMP(const DeckRecord& record);
470 bool handleWPIMULT(const DeckRecord& record);
471 bool applyGlobalWPIMULT(double scale_factor);
472
473 void filterConnections(const ActiveGridCells& grid);
474 ProductionControls productionControls(const SummaryState& st) const;
475 InjectionControls injectionControls(const SummaryState& st) const;
476 int vfp_table_number() const;
477 int pvt_table_number() const;
478 int fip_region_number() const;
479 GasInflowEquation gas_inflow_equation() const;
480 bool segmented_density_calculation() const { return true; }
481 double alq_value() const;
482 double temperature() const;
483 void setWellTemperature(const double temp);
484 bool hasInjected( ) const;
485 bool hasProduced( ) const;
486 bool updateHasInjected( );
487 bool updateHasProduced();
488 bool cmp_structure(const Well& other) const;
489 bool operator==(const Well& data) const;
490 bool hasSameConnectionsPointers(const Well& other) const;
491 void setInsertIndex(std::size_t index);
492 double convertDeckPI(double deckPI) const;
493 void applyWellProdIndexScaling(const double scalingFactor,
494 std::vector<bool>& scalingApplicable);
495 const PAvg& pavg() const;
496 PAvgCalculator pavg_calculator(const EclipseGrid& grid, const std::vector<double>& porv) const;
497
498 template<class Serializer>
499 void serializeOp(Serializer& serializer)
500 {
501 serializer(wname);
502 serializer(group_name);
503 serializer(init_step);
504 serializer(insert_index);
505 serializer(headI);
506 serializer(headJ);
507 serializer(ref_depth);
508 serializer(wpave_ref_depth);
509 serializer(unit_system);
510 serializer(udq_undefined);
511 serializer(status);
512 serializer(drainage_radius);
513 serializer(allow_cross_flow);
514 serializer(automatic_shutin);
515 serializer(pvt_table);
516 serializer(gas_inflow);
517 serializer(wtype);
518 serializer(guide_rate);
519 serializer(efficiency_factor);
520 serializer(solvent_fraction);
521 serializer(has_produced);
522 serializer(has_injected);
523 serializer(prediction_mode);
524 serializer(econ_limits);
525 serializer(foam_properties);
526 serializer(polymer_properties);
527 serializer(micp_properties);
528 serializer(brine_properties);
529 serializer(tracer_properties);
530 serializer(connections);
531 serializer(production);
532 serializer(injection);
533 serializer(segments);
534 serializer(wvfpexp);
535 serializer(m_pavg);
536 serializer(well_temperature);
537 }
538
539private:
540 void switchToInjector();
541 void switchToProducer();
542
543 GuideRateTarget preferredPhaseAsGuideRatePhase() const;
544
545 std::string wname;
546 std::string group_name;
547 std::size_t init_step;
548 std::size_t insert_index;
549 int headI;
550 int headJ;
551 std::optional<double> ref_depth;
552 std::optional<double> wpave_ref_depth;
553 double drainage_radius;
554 bool allow_cross_flow;
555 bool automatic_shutin;
556 int pvt_table;
557 GasInflowEquation gas_inflow = GasInflowEquation::STD; // Will NOT be loaded/assigned from restart file
558 UnitSystem unit_system;
559 double udq_undefined;
560 WellType wtype;
561 WellGuideRate guide_rate;
562 double efficiency_factor;
563 double solvent_fraction;
564 bool has_produced = false;
565 bool has_injected = false;
566 bool prediction_mode = true;
567
568 std::shared_ptr<WellEconProductionLimits> econ_limits;
569 std::shared_ptr<WellFoamProperties> foam_properties;
570 std::shared_ptr<WellPolymerProperties> polymer_properties;
571 std::shared_ptr<WellMICPProperties> micp_properties;
572 std::shared_ptr<WellBrineProperties> brine_properties;
573 std::shared_ptr<WellTracerProperties> tracer_properties;
574 std::shared_ptr<WellConnections> connections; // The WellConnections object cannot be const because of WELPI and the filterConnections method
575 std::shared_ptr<WellProductionProperties> production;
576 std::shared_ptr<WellInjectionProperties> injection;
577 std::shared_ptr<WellSegments> segments;
578 std::shared_ptr<WVFPEXP> wvfpexp;
579 Status status;
580 PAvg m_pavg;
581 double well_temperature;
582};
583
584std::ostream& operator<<( std::ostream&, const Well::WellInjectionProperties& );
585std::ostream& operator<<( std::ostream&, const Well::WellProductionProperties& );
586
587}
588#endif
Simple class capturing active cells of a grid.
Definition: ActiveGridCells.hpp:36
Definition: DeckKeyword.hpp:36
Definition: DeckRecord.hpp:32
About cell information and dimension: The actual grid information is held in a pointer to an ERT ecl_...
Definition: EclipseGrid.hpp:54
Definition: ErrorGuard.hpp:29
Definition: KeywordLocation.hpp:27
Definition: PAvgCalculator.hpp:37
Definition: PAvg.hpp:28
Definition: ParseContext.hpp:84
Definition: ScheduleGrid.hpp:29
Class for (de-)serializing.
Definition: Serializer.hpp:84
Definition: SummaryState.hpp:68
Definition: TracerConfig.hpp:33
Definition: UDAValue.hpp:32
Definition: UDQActive.hpp:43
Definition: UDQConfig.hpp:57
Definition: UnitSystem.hpp:33
Definition: WVFPEXP.hpp:34
Definition: WellConnections.hpp:45
Definition: WellEconProductionLimits.hpp:33
Definition: WellSegments.hpp:47
Definition: WellTracerProperties.hpp:28
Definition: ScheduleTypes.hpp:38
Definition: Well.hpp:218
Definition: Well.hpp:74
This class implements a small container which holds the transmissibility mulitpliers for all the face...
Definition: Exceptions.hpp:30
Definition: well.hpp:43
Definition: WellBrineProperties.hpp:29
Definition: WellFoamProperties.hpp:29
Definition: WellInjectionControls.hpp:29
Definition: WellMICPProperties.hpp:29
Definition: WellPolymerProperties.hpp:28
Definition: WellProductionControls.hpp:29
Definition: Well.hpp:98
Definition: Well.hpp:134