My Project
Loading...
Searching...
No Matches
BlackoilWellModelGeneric.hpp
1/*
2 Copyright 2016 SINTEF ICT, Applied Mathematics.
3 Copyright 2016 - 2017 Statoil ASA.
4 Copyright 2017 Dr. Blatt - HPC-Simulation-Software & Services
5 Copyright 2016 - 2018 IRIS AS
6
7 This file is part of the Open Porous Media project (OPM).
8
9 OPM is free software: you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
11 the Free Software Foundation, either version 3 of the License, or
12 (at your option) any later version.
13
14 OPM is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License for more details.
18
19 You should have received a copy of the GNU General Public License
20 along with OPM. If not, see <http://www.gnu.org/licenses/>.
21*/
22
23#ifndef OPM_BLACKOILWELLMODEL_GENERIC_HEADER_INCLUDED
24#define OPM_BLACKOILWELLMODEL_GENERIC_HEADER_INCLUDED
25
26#include <opm/output/data/GuideRateValue.hpp>
27
28#include <opm/input/eclipse/Schedule/Group/GuideRate.hpp>
29#include <opm/input/eclipse/Schedule/Well/PAvg.hpp>
30#include <opm/input/eclipse/Schedule/Well/PAvgCalculator.hpp>
31#include <opm/input/eclipse/Schedule/Well/PAvgCalculatorCollection.hpp>
32#include <opm/input/eclipse/Schedule/Well/WellTestState.hpp>
33
34#include <opm/simulators/utils/DeferredLoggingErrorHelpers.hpp>
35#include <opm/simulators/wells/BlackoilWellModelWBP.hpp>
36#include <opm/simulators/wells/ConnectionIndexMap.hpp>
37#include <opm/simulators/wells/ParallelPAvgDynamicSourceData.hpp>
38#include <opm/simulators/wells/ParallelWBPCalculation.hpp>
39#include <opm/simulators/wells/PerforationData.hpp>
40#include <opm/simulators/wells/WellFilterCake.hpp>
41#include <opm/simulators/wells/WellProdIndexCalculator.hpp>
42#include <opm/simulators/wells/WellTracerRate.hpp>
43#include <opm/simulators/wells/WGState.hpp>
44
45#include <cstddef>
46#include <functional>
47#include <map>
48#include <memory>
49#include <optional>
50#include <string>
51#include <unordered_map>
52#include <unordered_set>
53#include <vector>
54
55namespace Opm {
56 class DeferredLogger;
57 class EclipseState;
58 template<class Scalar> class BlackoilWellModelGasLiftGeneric;
59 template<class Scalar> class GasLiftGroupInfo;
60 template<class Scalar> class GasLiftSingleWellGeneric;
61 template<class Scalar> class GasLiftWellState;
62 class Group;
63 class GuideRateConfig;
64 template<class Scalar> class ParallelWellInfo;
65 class RestartValue;
66 class Schedule;
67 struct SimulatorUpdate;
68 class SummaryConfig;
69 template<class Scalar> class VFPProperties;
70 template<class Scalar> class WellInterfaceGeneric;
71 template<class Scalar> class WellState;
72} // namespace Opm
73
74namespace Opm { namespace data {
75 struct GroupData;
76 struct GroupGuideRates;
78 struct NodeData;
79}} // namespace Opm::data
80
81namespace Opm::Parameters {
82
83struct EnableTerminalOutput { static constexpr bool value = true; };
84
85} // namespace Opm::Parameters
86
87namespace Opm {
88
90template<class Scalar>
92{
93public:
96 const SummaryState& summaryState,
97 const EclipseState& eclState,
99 const Parallel::Communication& comm);
100
101 virtual ~BlackoilWellModelGeneric() = default;
102
103 int numLocalWells() const;
104 int numLocalWellsEnd() const;
105 int numLocalNonshutWells() const;
106 int numPhases() const;
107
109 bool wellsActive() const;
110
112 bool hasLocalWell(const std::string& wname) const;
113
115 bool hasOpenLocalWell(const std::string& well_name) const;
116
118 bool networkActive() const;
119
120 // whether there exists any multisegment well open on this process
121 bool anyMSWellOpenLocal() const;
122
123 const std::vector<Well>& eclWells() const
124 { return wells_ecl_; }
125
126 bool terminalOutput() const
127 { return terminal_output_; }
128
129 const Well& getWellEcl(const std::string& well_name) const;
130 std::vector<Well> getLocalWells(const int timeStepIdx) const;
131 const Schedule& schedule() const { return schedule_; }
132 const PhaseUsage& phaseUsage() const { return phase_usage_; }
133 const GroupState<Scalar>& groupState() const { return this->active_wgstate_.group_state; }
134 std::vector<const WellInterfaceGeneric<Scalar>*> genericWells() const
135 { return {well_container_generic_.begin(), well_container_generic_.end()}; }
136
137 std::vector<WellInterfaceGeneric<Scalar>*> genericWells()
138 { return well_container_generic_; }
139
140 /*
141 Immutable version of the currently active wellstate.
142 */
143 const WellState<Scalar>& wellState() const
144 {
145 return this->active_wgstate_.well_state;
146 }
147
148 /*
149 Mutable version of the currently active wellstate.
150 */
151 WellState<Scalar>& wellState()
152 {
153 return this->active_wgstate_.well_state;
154 }
155
156 /*
157 Will return the currently active nupcolWellState; must update
158 the internal nupcol wellstate with updateNupcolWGState() first.
159 */
160 const WellState<Scalar>& nupcolWellState() const
161 {
162 return this->nupcol_wgstate_.well_state;
163 }
164 GroupState<Scalar>& groupState() { return this->active_wgstate_.group_state; }
165
166 WellTestState& wellTestState() { return this->active_wgstate_.well_test_state; }
167
168 const WellTestState& wellTestState() const { return this->active_wgstate_.well_test_state; }
169
170 Scalar wellPI(const int well_index) const;
171 Scalar wellPI(const std::string& well_name) const;
172
173 void updateEclWells(const int timeStepIdx,
175 const SummaryState& st);
176
177 void initFromRestartFile(const RestartValue& restartValues,
178 std::unique_ptr<WellTestState> wtestState,
179 const std::size_t numCells,
180 bool handle_ms_well);
181
182 void prepareDeserialize(int report_step,
183 const std::size_t numCells,
184 bool handle_ms_well);
185
186 /*
187 Will assign the internal member last_valid_well_state_ to the
188 current value of the this->active_well_state_. The state stored
189 with storeWellState() can then subsequently be recovered with the
190 resetWellState() method.
191 */
192 void commitWGState()
193 {
194 this->last_valid_wgstate_ = this->active_wgstate_;
195 }
196
197 data::GroupAndNetworkValues groupAndNetworkData(const int reportStepIdx) const;
198
200 void updateNetworkActiveState(const int report_step);
201
205 bool needPreStepNetworkRebalance(const int report_step) const;
206
209 bool forceShutWellByName(const std::string& wellname,
210 const double simulation_time,
211 const bool dont_shut_grup_wells);
212
213 const std::vector<PerforationData<Scalar>>& perfData(const int well_idx) const
214 { return well_perf_data_[well_idx]; }
215
216 const Parallel::Communication& comm() const { return comm_; }
217
218 const EclipseState& eclipseState() const { return eclState_; }
219
220 const SummaryState& summaryState() const { return summaryState_; }
221
222 const GuideRate& guideRate() const { return guideRate_; }
223
224 const std::map<std::string, double>& wellOpenTimes() const { return well_open_times_; }
225 const std::map<std::string, double>& wellCloseTimes() const { return well_close_times_; }
226 const WellGroupEvents& reportStepStartEvents() const { return report_step_start_events_; }
227
228 std::vector<int> getCellsForConnections(const Well& well) const;
229
230 bool reportStepStarts() const { return report_step_starts_; }
231
232 bool shouldBalanceNetwork(const int reportStepIndex,
233 const int iterationIdx) const;
234
235 void updateClosedWellsThisStep(const std::string& well_name) const
236 {
237 this->closed_this_step_.insert(well_name);
238 }
239 bool wasDynamicallyShutThisTimeStep(const std::string& well_name) const;
240
241 void logPrimaryVars() const;
242
243 template<class Serializer>
244 void serializeOp(Serializer& serializer)
245 {
246 serializer(initial_step_);
247 serializer(report_step_starts_);
248 serializer(last_run_wellpi_);
249 serializer(local_shut_wells_);
250 serializer(closed_this_step_);
251 serializer(guideRate_);
252 serializer(node_pressures_);
253 serializer(prev_inj_multipliers_);
254 serializer(active_wgstate_);
255 serializer(last_valid_wgstate_);
256 serializer(nupcol_wgstate_);
257 serializer(switched_prod_groups_);
258 serializer(switched_inj_groups_);
259 serializer(closed_offending_wells_);
260 serializer(gen_gaslift_);
261 }
262
263 bool operator==(const BlackoilWellModelGeneric& rhs) const;
264
266 parallelWellInfo(const std::size_t idx) const
267 { return local_parallel_well_info_[idx].get(); }
268
269 const ConnectionIndexMap& connectionIndexMap(const std::size_t idx)
270 { return conn_idx_map_[idx]; }
271
272protected:
273 /*
274 The dynamic state of the well model is maintained with an instance
275 of the WellState class. Currently we have
276 three different wellstate instances:
277
278 1. The currently active wellstate is in the active_well_state_
279 member. That is the state which is mutated by the simulator.
280
281 2. In the case timestep fails to converge and we must go back and
282 try again with a smaller timestep we need to recover the last
283 valid wellstate. This is maintained with the
284 last_valid_well_state_ member and the functions
285 commitWGState() and resetWellState().
286
287 3. For the NUPCOL functionality we should either use the
288 currently active wellstate or a wellstate frozen at max
289 nupcol iterations. This is handled with the member
290 nupcol_well_state_ and the updateNupcolWGState() function.
291 */
292
293 /*
294 Will return the last good wellstate. This is typcially used when
295 initializing a new report step where the Schedule object might
296 have introduced new wells. The wellstate returned by
297 prevWellState() must have been stored with the commitWGState()
298 function first.
299 */
300 const WellState<Scalar>& prevWellState() const
301 {
302 return this->last_valid_wgstate_.well_state;
303 }
304
305 const WGState<Scalar>& prevWGState() const
306 {
307 return this->last_valid_wgstate_;
308 }
309
310 /*
311 Will store a copy of the input argument well_state in the
312 last_valid_well_state_ member, that state can then be recovered
313 with a subsequent call to resetWellState().
314 */
315 void commitWGState(WGState<Scalar> wgstate)
316 {
317 this->last_valid_wgstate_ = std::move(wgstate);
318 }
319
320 /*
321 Will update the internal variable active_well_state_ to whatever
322 was stored in the last_valid_well_state_ member. This function
323 works in pair with commitWellState() which should be called first.
324 */
325 void resetWGState()
326 {
327 this->active_wgstate_ = this->last_valid_wgstate_;
328 }
329
330 /*
331 Will store the current active wellstate in the nupcol_well_state_
332 member. This can then be subsequently retrieved with accessor
333 nupcolWellState().
334 */
335 void updateNupcolWGState()
336 {
337 this->nupcol_wgstate_ = this->active_wgstate_;
338 }
339
340 void reportGroupSwitching(DeferredLogger& local_deferredLogger) const;
341
344 std::vector<std::reference_wrapper<ParallelWellInfo<Scalar>>>
345 createLocalParallelWellInfo(const std::vector<Well>& wells);
346
347 void initializeWellProdIndCalculators();
348 void initializeWellPerfData();
349
350 bool wasDynamicallyShutThisTimeStep(const int well_index) const;
351
352 Scalar updateNetworkPressures(const int reportStepIdx,
353 const Scalar damping_factor,
354 const Scalar update_upper_bound);
355
356 void updateWsolvent(const Group& group,
357 const int reportStepIdx,
358 const WellState<Scalar>& wellState);
359 void setWsolvent(const Group& group,
360 const int reportStepIdx,
361 Scalar wsolvent);
362 virtual void calcResvCoeff(const int fipnum,
363 const int pvtreg,
364 const std::vector<Scalar>& production_rates,
365 std::vector<Scalar>& resv_coeff) = 0;
366 virtual void calcInjResvCoeff(const int fipnum,
367 const int pvtreg,
368 std::vector<Scalar>& resv_coeff) = 0;
369
370 void assignShutConnections(data::Wells& wsrpt,
371 const int reportStepIndex) const;
372 void assignWellTargets(data::Wells& wsrpt) const;
373 void assignProductionWellTargets(const Well& well, data::WellControlLimits& limits) const;
374 void assignInjectionWellTargets(const Well& well, data::WellControlLimits& limits) const;
375 void assignGroupControl(const Group& group,
376 data::GroupData& gdata) const;
377 void assignGroupValues(const int reportStepIdx,
378 std::map<std::string, data::GroupData>& gvalues) const;
379 void assignNodeValues(std::map<std::string, data::NodeData>& nodevalues,
380 const int reportStepIdx) const;
381
382 void calculateEfficiencyFactors(const int reportStepIdx);
383
384 void checkGconsaleLimits(const Group& group,
385 WellState<Scalar>& well_state,
386 const int reportStepIdx,
388
389 void checkGEconLimits(const Group& group,
390 const double simulation_time,
391 const int report_step_idx,
393
394 bool checkGroupHigherConstraints(const Group& group,
396 const int reportStepIdx,
398
399 void updateAndCommunicateGroupData(const int reportStepIdx,
400 const int iterationIdx,
401 const Scalar tol_nupcol,
403
404 void inferLocalShutWells();
405
406 void setRepRadiusPerfLength();
407
408 virtual void computePotentials(const std::size_t widx,
410 std::string& exc_msg,
411 ExceptionType::ExcEnum& exc_type,
413
414 // Calculating well potentials for each well
415 void updateWellPotentials(const int reportStepIdx,
416 const bool onlyAfterEvent,
417 const SummaryConfig& summaryConfig,
419
420 void initInjMult();
421
422 void updateInjMult(DeferredLogger& deferred_logger);
423 void updateInjFCMult(DeferredLogger& deferred_logger);
424
425 void updateFiltrationModelsPostStep(const double dt,
426 const std::size_t water_index,
428
429 void updateFiltrationModelsPreStep(DeferredLogger& deferred_logger);
430
431 // create the well container
432 virtual void createWellContainer(const int time_step) = 0;
433 virtual void initWellContainer(const int reportStepIdx) = 0;
434
435 virtual void calculateProductivityIndexValuesShutWells(const int reportStepIdx,
437 virtual void calculateProductivityIndexValues(DeferredLogger& deferred_logger) = 0;
438
439 void runWellPIScaling(const int reportStepIdx,
441
444
445 std::vector<std::vector<int>> getMaxWellConnections() const;
446
447 std::vector<std::string> getWellsForTesting(const int timeStepIdx,
448 const double simulationTime);
449
450 using WellTracerRates = std::unordered_map<int, std::vector<WellTracerRate<Scalar>>>;
451 void assignWellTracerRates(data::Wells& wsrpt,
452 const WellTracerRates& wellTracerRates,
453 const unsigned reportStep) const;
454
455 using MswTracerRates = std::unordered_map<int, std::vector<MSWellTracerRate<Scalar>>>;
456 void assignMswTracerRates(data::Wells& wsrpt,
457 const MswTracerRates& mswTracerRates,
458 const unsigned reportStep) const;
459
460 void assignMassGasRate(data::Wells& wsrpt,
461 const Scalar& gasDensity) const;
462
463 Schedule& schedule_;
464 const SummaryState& summaryState_;
465 const EclipseState& eclState_;
466 const Parallel::Communication& comm_;
469
470 PhaseUsage phase_usage_;
471 bool terminal_output_{false};
472 bool wells_active_{false};
473 bool network_active_{false};
474 bool initial_step_{};
475 bool report_step_starts_{};
476
477 std::optional<int> last_run_wellpi_{};
478
479 std::vector<Well> wells_ecl_;
480 std::vector<std::vector<PerforationData<Scalar>>> well_perf_data_;
481
482 // Times at which wells were opened (for WCYCLE)
483 std::map<std::string, double> well_open_times_;
484
485 // Times at which wells were shut (for WCYCLE)
486 std::map<std::string, double> well_close_times_;
487
488 std::vector<ConnectionIndexMap> conn_idx_map_{};
489 std::function<bool(const Well&)> not_on_process_{};
490
491 // a vector of all the wells.
492 std::vector<WellInterfaceGeneric<Scalar>*> well_container_generic_{};
493
494 std::vector<int> local_shut_wells_{};
495
496 std::vector<ParallelWellInfo<Scalar>> parallel_well_info_;
497 std::vector<std::reference_wrapper<ParallelWellInfo<Scalar>>> local_parallel_well_info_;
498
499 std::vector<WellProdIndexCalculator<Scalar>> prod_index_calc_;
500
501 std::vector<int> pvt_region_idx_;
502
503 mutable std::unordered_set<std::string> closed_this_step_;
504
505 GuideRate guideRate_;
506 std::unique_ptr<VFPProperties<Scalar>> vfp_properties_{};
507 std::map<std::string, Scalar> node_pressures_; // Storing network pressures for output.
508
509 // previous injection multiplier, it is used in the injection multiplier calculation for WINJMULT keyword
510 std::unordered_map<std::string, std::vector<Scalar>> prev_inj_multipliers_;
511
512 // Handling for filter cake injection multipliers
513 std::unordered_map<std::string, WellFilterCake<Scalar>> filter_cake_;
514
515 /*
516 The various wellState members should be accessed and modified
517 through the accessor functions wellState(), prevWellState(),
518 commitWellState(), resetWellState(), nupcolWellState() and
519 updateNupcolWGState().
520 */
521 WGState<Scalar> active_wgstate_;
522 WGState<Scalar> last_valid_wgstate_;
523 WGState<Scalar> nupcol_wgstate_;
525
526 bool wellStructureChangedDynamically_{false};
527
528 // Store maps of group name and new group controls for output
529 std::map<std::string, std::vector<Group::ProductionCMode>> switched_prod_groups_;
530 std::map<std::string, std::array<std::vector<Group::InjectionCMode>, 3>> switched_inj_groups_;
531 // Store map of group name and close offending well for output
532 std::map<std::string, std::pair<std::string, std::string>> closed_offending_wells_;
533
534private:
535 WellInterfaceGeneric<Scalar>* getGenWell(const std::string& well_name);
536
537 template <typename Iter, typename Body>
538 void wellUpdateLoop(Iter first, Iter last, const int timeStepIdx, Body&& body);
539
540 void updateEclWellsConstraints(const int timeStepIdx,
542 const SummaryState& st);
543
544 void updateEclWellsCTFFromAction(const int timeStepIdx,
546};
547
548
549} // namespace Opm
550
551#endif
Definition BlackoilWellModelGasLift.hpp:41
Class for handling the blackoil well model.
Definition BlackoilWellModelGeneric.hpp:92
void updateNetworkActiveState(const int report_step)
Checks if network is active (at least one network well on prediction).
Definition BlackoilWellModelGeneric.cpp:1411
bool hasLocalWell(const std::string &wname) const
Returns true if well is defined and has connections on current rank.
Definition BlackoilWellModelGeneric.cpp:154
bool wellsActive() const
return true if wells are available in the reservoir
Definition BlackoilWellModelGeneric.cpp:179
bool hasOpenLocalWell(const std::string &well_name) const
Returns true if well is defined, open and has connections on current rank.
Definition BlackoilWellModelGeneric.cpp:167
bool networkActive() const
return true if network is active (at least one network well in prediction mode)
Definition BlackoilWellModelGeneric.cpp:186
bool forceShutWellByName(const std::string &wellname, const double simulation_time, const bool dont_shut_grup_wells)
Shut down any single well Returns true if the well was actually found and shut.
Definition BlackoilWellModelGeneric.cpp:1451
WellGroupEvents report_step_start_events_
Well group events at start of report step.
Definition BlackoilWellModelGeneric.hpp:524
std::vector< std::reference_wrapper< ParallelWellInfo< Scalar > > > createLocalParallelWellInfo(const std::vector< Well > &wells)
Create the parallel well information.
Definition BlackoilWellModelGeneric.cpp:310
bool needPreStepNetworkRebalance(const int report_step) const
Checks if there are reasons to perform a pre-step network re-balance.
Definition BlackoilWellModelGeneric.cpp:1432
virtual int compressedIndexForInterior(int cartesian_cell_idx) const =0
get compressed index for interior cells (-1, otherwise
Class for handling the blackoil well model.
Definition BlackoilWellModelWBP.hpp:42
Connection index mappings.
Definition ConnectionIndexMap.hpp:33
Definition DeferredLogger.hpp:57
Definition GroupState.hpp:43
Class encapsulating some information about parallel wells.
Definition ParallelWellInfo.hpp:195
Definition WellInterfaceGeneric.hpp:53
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 blackoilboundaryratevector.hh:37
constexpr auto getPropValue()
get the value data member of a property
Definition propertysystem.hh:242
Definition BlackoilWellModelGeneric.hpp:83
Definition BlackoilPhases.hpp:46
Definition WGState.hpp:41