My Project
Wells.hpp
1/*
2 Copyright 2016 Statoil 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_OUTPUT_WELLS_HPP
21#define OPM_OUTPUT_WELLS_HPP
22
23#include <algorithm>
24#include <cstddef>
25#include <initializer_list>
26#include <map>
27#include <stdexcept>
28#include <string>
29#include <type_traits>
30#include <unordered_map>
31#include <vector>
32
33#include <opm/json/JsonObject.hpp>
34#include <opm/output/data/GuideRateValue.hpp>
35#include <opm/input/eclipse/Schedule/Well/Well.hpp>
36
37namespace Opm {
38
39 namespace data {
40
41 class Rates {
42 /* Methods are defined inline for performance, as the actual *work* done
43 * is trivial, but somewhat frequent (typically once per time step per
44 * completion per well).
45 *
46 * To add a new rate type, add an entry in the enum with the correct
47 * shift, and if needed, increase the size type. Add a member variable
48 * and a new case in get_ref.
49 */
50
51 public:
52 Rates() = default;
53 enum class opt : uint32_t {
54 wat = (1 << 0),
55 oil = (1 << 1),
56 gas = (1 << 2),
57 polymer = (1 << 3),
58 solvent = (1 << 4),
59 energy = (1 << 5),
60 dissolved_gas = (1 << 6),
61 vaporized_oil = (1 << 7),
62 reservoir_water = (1 << 8),
63 reservoir_oil = (1 << 9),
64 reservoir_gas = (1 << 10),
65 productivity_index_water = (1 << 11),
66 productivity_index_oil = (1 << 12),
67 productivity_index_gas = (1 << 13),
68 well_potential_water = (1 << 14),
69 well_potential_oil = (1 << 15),
70 well_potential_gas = (1 << 16),
71 brine = (1 << 17),
72 alq = (1 << 18),
73 tracer = (1 << 19),
74 micp = (1 << 20),
75 vaporized_water = (1 << 21)
76 };
77
78 using enum_size = std::underlying_type< opt >::type;
79
81 inline bool has( opt ) const;
82
85 inline double get( opt m ) const;
88 inline double get( opt m, double default_value ) const;
89 inline double get( opt m, double default_value , const std::string& tracer_name ) const;
93 inline Rates& set( opt m, double value );
94 inline Rates& set( opt m, double value , const std::string& tracer_name );
95
97 inline bool flowing() const;
98
99 template <class MessageBufferType>
100 void write(MessageBufferType& buffer) const;
101 template <class MessageBufferType>
102 void read(MessageBufferType& buffer);
103
104 bool operator==(const Rates& rat2) const;
105
106 inline void init_json(Json::JsonObject& json_data) const;
107
108 template<class Serializer>
109 void serializeOp(Serializer& serializer)
110 {
111 serializer(mask);
112 serializer(wat);
113 serializer(oil);
114 serializer(gas);
115 serializer(polymer);
116 serializer(solvent);
117 serializer(energy);
118 serializer(dissolved_gas);
119 serializer(vaporized_oil);
120 serializer(reservoir_water);
121 serializer(reservoir_oil);
122 serializer(reservoir_gas);
123 serializer(productivity_index_water);
124 serializer(productivity_index_oil);
125 serializer(productivity_index_gas);
126 serializer(well_potential_water);
127 serializer(well_potential_oil);
128 serializer(well_potential_gas);
129 serializer(brine);
130 serializer(alq);
131 serializer(tracer);
132 serializer(micp);
133 serializer(vaporized_water);
134 }
135
136 static Rates serializationTestObject()
137 {
138 Rates rat1;
139 rat1.set(opt::wat, 1.0);
140 rat1.set(opt::oil, 2.0);
141 rat1.set(opt::gas, 3.0);
142 rat1.set(opt::polymer, 4.0);
143 rat1.set(opt::solvent, 5.0);
144 rat1.set(opt::energy, 6.0);
145 rat1.set(opt::dissolved_gas, 7.0);
146 rat1.set(opt::vaporized_oil, 8.0);
147 rat1.set(opt::reservoir_water, 9.0);
148 rat1.set(opt::reservoir_oil, 10.0);
149 rat1.set(opt::reservoir_gas, 11.0);
150 rat1.set(opt::productivity_index_water, 12.0);
151 rat1.set(opt::productivity_index_oil, 13.0);
152 rat1.set(opt::productivity_index_gas, 14.0);
153 rat1.set(opt::well_potential_water, 15.0);
154 rat1.set(opt::well_potential_oil, 16.0);
155 rat1.set(opt::well_potential_gas, 17.0);
156 rat1.set(opt::brine, 18.0);
157 rat1.set(opt::alq, 19.0);
158 rat1.set(opt::micp, 21.0);
159 rat1.set(opt::vaporized_water, 22.0);
160 rat1.tracer.insert({"test_tracer", 1.0});
161
162 return rat1;
163 }
164
165 private:
166 double& get_ref( opt );
167 double& get_ref( opt, const std::string& tracer_name );
168 const double& get_ref( opt ) const;
169 const double& get_ref( opt, const std::string& tracer_name ) const;
170
171 opt mask = static_cast< opt >( 0 );
172
173 double wat = 0.0;
174 double oil = 0.0;
175 double gas = 0.0;
176 double polymer = 0.0;
177 double solvent = 0.0;
178 double energy = 0.0;
179 double dissolved_gas = 0.0;
180 double vaporized_oil = 0.0;
181 double reservoir_water = 0.0;
182 double reservoir_oil = 0.0;
183 double reservoir_gas = 0.0;
184 double productivity_index_water = 0.0;
185 double productivity_index_oil = 0.0;
186 double productivity_index_gas = 0.0;
187 double well_potential_water = 0.0;
188 double well_potential_oil = 0.0;
189 double well_potential_gas = 0.0;
190 double brine = 0.0;
191 double alq = 0.0;
192 std::map<std::string, double> tracer;
193 double micp = 0.0;
194 double vaporized_water = 0.0;
195 };
196
197 struct Connection {
198 using global_index = size_t;
199 static const constexpr int restart_size = 6;
200
201 global_index index;
202 Rates rates;
203 double pressure;
204 double reservoir_rate;
205 double cell_pressure;
206 double cell_saturation_water;
207 double cell_saturation_gas;
208 double effective_Kh;
209 double trans_factor;
210
211 bool operator==(const Connection& conn2) const
212 {
213 return index == conn2.index &&
214 rates == conn2.rates &&
215 pressure == conn2.pressure &&
216 reservoir_rate == conn2.reservoir_rate &&
217 cell_pressure == conn2.cell_pressure &&
218 cell_saturation_water == conn2.cell_saturation_water &&
219 cell_saturation_gas == conn2.cell_saturation_gas &&
220 effective_Kh == conn2.effective_Kh &&
221 trans_factor == conn2.trans_factor;
222 }
223
224 template <class MessageBufferType>
225 void write(MessageBufferType& buffer) const;
226 template <class MessageBufferType>
227 void read(MessageBufferType& buffer);
228
229 inline void init_json(Json::JsonObject& json_data) const;
230
231 template<class Serializer>
232 void serializeOp(Serializer& serializer)
233 {
234 serializer(index);
235 serializer(rates);
236 serializer(pressure);
237 serializer(reservoir_rate);
238 serializer(cell_pressure);
239 serializer(cell_saturation_water);
240 serializer(cell_saturation_gas);
241 serializer(effective_Kh);
242 serializer(trans_factor);
243 }
244
245 static Connection serializationTestObject()
246 {
247 return Connection{1, Rates::serializationTestObject(),
248 2.0, 3.0, 4.0, 5.0,
249 6.0, 7.0, 8.0};
250 }
251 };
252
254 public:
255 enum class Value : std::size_t {
256 Pressure, PDrop, PDropHydrostatic, PDropAccel, PDropFriction,
257 };
258
259 double& operator[](const Value i)
260 {
261 return this->values_[this->index(i)];
262 }
263
264 double operator[](const Value i) const
265 {
266 return this->values_[this->index(i)];
267 }
268
269 bool operator==(const SegmentPressures& segpres2) const
270 {
271 return this->values_ == segpres2.values_;
272 }
273
274 template <class MessageBufferType>
275 void write(MessageBufferType& buffer) const
276 {
277 for (const auto& value : this->values_) {
278 buffer.write(value);
279 }
280 }
281
282 template <class MessageBufferType>
283 void read(MessageBufferType& buffer)
284 {
285 for (auto& value : this->values_) {
286 buffer.read(value);
287 }
288 }
289
290 template<class Serializer>
291 void serializeOp(Serializer& serializer)
292 {
293 serializer(values_);
294 }
295
296 static SegmentPressures serializationTestObject()
297 {
298 SegmentPressures spres;
299 spres[Value::Pressure] = 1.0;
300 spres[Value::PDrop] = 2.0;
301 spres[Value::PDropHydrostatic] = 3.0;
302 spres[Value::PDropAccel] = 4.0;
303 spres[Value::PDropFriction] = 5.0;
304
305 return spres;
306 }
307
308 private:
309 constexpr static std::size_t numvals = 5;
310
311 std::array<double, numvals> values_ = {0};
312
313 std::size_t index(const Value ix) const
314 {
315 return static_cast<std::size_t>(ix);
316 }
317 };
318
319 struct Segment {
320 Rates rates;
321 SegmentPressures pressures;
322 std::size_t segNumber;
323
324 bool operator==(const Segment& seg2) const
325 {
326 return rates == seg2.rates &&
327 pressures == seg2.pressures &&
328 segNumber == seg2.segNumber;
329 }
330
331 template <class MessageBufferType>
332 void write(MessageBufferType& buffer) const;
333
334 template <class MessageBufferType>
335 void read(MessageBufferType& buffer);
336
337 template<class Serializer>
338 void serializeOp(Serializer& serializer)
339 {
340 serializer(rates);
341 serializer(pressures);
342 serializer(segNumber);
343 }
344
345 static Segment serializationTestObject()
346 {
347 return Segment{Rates::serializationTestObject(),
348 SegmentPressures::serializationTestObject(),
349 10
350 };
351 }
352 };
353
355 bool isProducer{true};
356
357 ::Opm::Well::ProducerCMode prod {
358 ::Opm::Well::ProducerCMode::CMODE_UNDEFINED
359 };
360
361 ::Opm::Well::InjectorCMode inj {
362 ::Opm::Well::InjectorCMode::CMODE_UNDEFINED
363 };
364
365 bool operator==(const CurrentControl& rhs) const
366 {
367 return (this->isProducer == rhs.isProducer)
368 && ((this->isProducer && (this->prod == rhs.prod)) ||
369 (!this->isProducer && (this->inj == rhs.inj)));
370 }
371
372 void init_json(Json::JsonObject& json_data) const
373 {
374 if (this->inj == ::Opm::Well::InjectorCMode::CMODE_UNDEFINED)
375 json_data.add_item("inj", "CMODE_UNDEFINED");
376 else
377 json_data.add_item("inj", ::Opm::Well::InjectorCMode2String(this->inj));
378
379 if (this->prod == ::Opm::Well::ProducerCMode::CMODE_UNDEFINED)
380 json_data.add_item("prod", "CMODE_UNDEFINED");
381 else
382 json_data.add_item("prod", ::Opm::Well::ProducerCMode2String(this->prod));
383 }
384
385 template <class MessageBufferType>
386 void write(MessageBufferType& buffer) const;
387
388 template <class MessageBufferType>
389 void read(MessageBufferType& buffer);
390
391 template<class Serializer>
392 void serializeOp(Serializer& serializer)
393 {
394 serializer(isProducer);
395 serializer(prod);
396 serializer(inj);
397 }
398
399 static CurrentControl serializationTestObject()
400 {
401 return CurrentControl{false,
402 ::Opm::Well::ProducerCMode::BHP,
403 ::Opm::Well::InjectorCMode::GRUP
404 };
405 }
406 };
407
408 struct Well {
409 Rates rates{};
410 double bhp{0.0};
411 double thp{0.0};
412 double temperature{0.0};
413 int control{0};
414
415 ::Opm::Well::Status dynamicStatus { Opm::Well::Status::OPEN };
416
417 std::vector< Connection > connections{};
418 std::unordered_map<std::size_t, Segment> segments{};
419 CurrentControl current_control{};
420 GuideRateValue guide_rates{};
421
422 inline bool flowing() const noexcept;
423 template <class MessageBufferType>
424 void write(MessageBufferType& buffer) const;
425 template <class MessageBufferType>
426 void read(MessageBufferType& buffer);
427
428 inline void init_json(Json::JsonObject& json_data) const;
429
430 const Connection* find_connection(Connection::global_index connection_grid_index) const {
431 const auto connection = std::find_if( this->connections.begin() ,
432 this->connections.end() ,
433 [=]( const Connection& c ) {
434 return c.index == connection_grid_index; });
435
436 if( connection == this->connections.end() )
437 return nullptr;
438
439 return &*connection;
440 }
441
442 Connection* find_connection(Connection::global_index connection_grid_index) {
443 auto connection = std::find_if( this->connections.begin() ,
444 this->connections.end() ,
445 [=]( const Connection& c ) {
446 return c.index == connection_grid_index; });
447
448 if( connection == this->connections.end() )
449 return nullptr;
450
451 return &*connection;
452 }
453
454 bool operator==(const Well& well2) const
455 {
456 return rates == well2.rates &&
457 bhp == well2.bhp &&
458 thp == well2.thp &&
459 temperature == well2.temperature &&
460 control == well2.control &&
461 dynamicStatus == well2.dynamicStatus &&
462 connections == well2.connections &&
463 segments == well2.segments &&
464 current_control == well2.current_control &&
465 guide_rates == well2.guide_rates;
466 }
467
468 template<class Serializer>
469 void serializeOp(Serializer& serializer)
470 {
471 serializer(rates);
472 serializer(bhp);
473 serializer(thp);
474 serializer(temperature);
475 serializer(control);
476 serializer(dynamicStatus);
477 serializer(connections);
478 serializer(segments);
479 serializer(current_control);
480 serializer(guide_rates);
481 }
482
483 static Well serializationTestObject()
484 {
485 return Well{Rates::serializationTestObject(),
486 1.0,
487 2.0,
488 3.0,
489 4,
490 ::Opm::Well::Status::SHUT,
491 {Connection::serializationTestObject()},
492 {{0, Segment::serializationTestObject()}},
493 CurrentControl::serializationTestObject(),
494 GuideRateValue::serializationTestObject()
495 };
496 }
497 };
498
499
500 class Wells: public std::map<std::string , Well> {
501 public:
502
503 double get(const std::string& well_name , Rates::opt m) const {
504 const auto& well = this->find( well_name );
505 if( well == this->end() ) return 0.0;
506
507 return well->second.rates.get( m, 0.0 );
508 }
509
510 double get(const std::string& well_name , Rates::opt m, const std::string& tracer_name) const {
511 const auto& well = this->find( well_name );
512 if( well == this->end() ) return 0.0;
513
514 return well->second.rates.get( m, 0.0, tracer_name);
515 }
516
517 double get(const std::string& well_name , Connection::global_index connection_grid_index, Rates::opt m) const {
518 const auto& witr = this->find( well_name );
519 if( witr == this->end() ) return 0.0;
520
521 const auto& well = witr->second;
522 const auto& connection = std::find_if( well.connections.begin() ,
523 well.connections.end() ,
524 [=]( const Connection& c ) {
525 return c.index == connection_grid_index; });
526
527 if( connection == well.connections.end() )
528 return 0.0;
529
530 return connection->rates.get( m, 0.0 );
531 }
532
533 template <class MessageBufferType>
534 void write(MessageBufferType& buffer) const {
535 unsigned int size = this->size();
536 buffer.write(size);
537 for (const auto& witr : *this) {
538 const std::string& name = witr.first;
539 buffer.write(name);
540 const Well& well = witr.second;
541 well.write(buffer);
542 }
543 }
544
545 template <class MessageBufferType>
546 void read(MessageBufferType& buffer) {
547 unsigned int size;
548 buffer.read(size);
549 for (size_t i = 0; i < size; ++i) {
550 std::string name;
551 buffer.read(name);
552 Well well;
553 well.read(buffer);
554 this->emplace(name, well);
555 }
556 }
557
558 void init_json(Json::JsonObject& json_data) const {
559 for (const auto& [wname, well] : *this) {
560 auto json_well = json_data.add_object(wname);
561 well.init_json(json_well);
562 }
563 }
564
565
566 Json::JsonObject json() const {
567 Json::JsonObject json_data;
568 this->init_json(json_data);
569 return json_data;
570 }
571
572 template<class Serializer>
573 void serializeOp(Serializer& serializer)
574 {
575 serializer(static_cast<std::map<std::string,Well>&>(*this));
576 }
577
578 static Wells serializationTestObject()
579 {
580 Wells w;
581 w.insert({"test_well", Well::serializationTestObject()});
582
583 return w;
584 }
585 };
586
587
588 /* IMPLEMENTATIONS */
589
590 inline bool Rates::has( opt m ) const {
591 const auto mand = static_cast< enum_size >( this->mask )
592 & static_cast< enum_size >( m );
593
594 return static_cast< opt >( mand ) == m;
595 }
596
597 inline double Rates::get( opt m ) const {
598 if( !this->has( m ) )
599 throw std::invalid_argument( "Uninitialized value." );
600
601 return this->get_ref( m );
602 }
603
604 inline double Rates::get( opt m, double default_value ) const {
605 if( !this->has( m ) ) return default_value;
606
607 return this->get_ref( m );
608 }
609
610 inline double Rates::get( opt m, double default_value, const std::string& tracer_name) const {
611 if( !this->has( m ) ) return default_value;
612
613 if( m == opt::tracer && this->tracer.find(tracer_name) == this->tracer.end()) return default_value;
614
615 return this->get_ref( m, tracer_name);
616 }
617
618 inline Rates& Rates::set( opt m, double value ) {
619 this->get_ref( m ) = value;
620
621 /* mask |= m */
622 this->mask = static_cast< opt >(
623 static_cast< enum_size >( this->mask ) |
624 static_cast< enum_size >( m )
625 );
626
627 return *this;
628 }
629
630 inline Rates& Rates::set( opt m, double value , const std::string& tracer_name ) {
631 this->get_ref( m , tracer_name) = value;
632
633 /* mask |= m */
634 this->mask = static_cast< opt >(
635 static_cast< enum_size >( this->mask ) |
636 static_cast< enum_size >( m )
637 );
638
639 return *this;
640 }
641
642 inline bool Rates::operator==(const Rates& rate) const
643 {
644 return mask == rate.mask &&
645 wat == rate.wat &&
646 oil == rate.oil &&
647 gas == rate.gas &&
648 polymer == rate.polymer &&
649 solvent == rate.solvent &&
650 energy == rate.energy &&
651 dissolved_gas == rate.dissolved_gas &&
652 vaporized_oil == rate.vaporized_oil &&
653 reservoir_water == rate.reservoir_water &&
654 reservoir_oil == rate.reservoir_oil &&
655 reservoir_gas == rate.reservoir_gas &&
656 productivity_index_water == rate.productivity_index_water &&
657 productivity_index_gas == rate.productivity_index_gas &&
658 productivity_index_oil == rate.productivity_index_oil &&
659 well_potential_water == rate.well_potential_water &&
660 well_potential_oil == rate.well_potential_oil &&
661 well_potential_gas == rate.well_potential_gas &&
662 brine == rate.brine &&
663 alq == rate.alq &&
664 tracer == rate.tracer &&
665 micp == rate.micp &&
666 vaporized_water == rate.vaporized_water;
667 }
668
669
670 /*
671 * To avoid error-prone and repetitve work when extending rates with new
672 * values, the get+set methods use this helper get_ref to determine what
673 * member to manipulate. To add a new option, just add another case
674 * corresponding to the enum entry in Rates to this function.
675 *
676 * This is an implementation detail and understanding this has no
677 * significant impact on correct use of the class.
678 */
679 inline const double& Rates::get_ref( opt m ) const {
680 switch( m ) {
681 case opt::wat: return this->wat;
682 case opt::oil: return this->oil;
683 case opt::gas: return this->gas;
684 case opt::polymer: return this->polymer;
685 case opt::solvent: return this->solvent;
686 case opt::energy: return this->energy;
687 case opt::dissolved_gas: return this->dissolved_gas;
688 case opt::vaporized_oil: return this->vaporized_oil;
689 case opt::reservoir_water: return this->reservoir_water;
690 case opt::reservoir_oil: return this->reservoir_oil;
691 case opt::reservoir_gas: return this->reservoir_gas;
692 case opt::productivity_index_water: return this->productivity_index_water;
693 case opt::productivity_index_oil: return this->productivity_index_oil;
694 case opt::productivity_index_gas: return this->productivity_index_gas;
695 case opt::well_potential_water: return this->well_potential_water;
696 case opt::well_potential_oil: return this->well_potential_oil;
697 case opt::well_potential_gas: return this->well_potential_gas;
698 case opt::brine: return this->brine;
699 case opt::alq: return this->alq;
700 case opt::tracer: /* Should _not_ be called with tracer argument */
701 break;
702 case opt::micp: return this->micp;
703 case opt::vaporized_water: return this->vaporized_water;
704 }
705
706 throw std::invalid_argument(
707 "Unknown value type '"
708 + std::to_string( static_cast< enum_size >( m ) )
709 + "'" );
710
711 }
712
713 inline const double& Rates::get_ref( opt m, const std::string& tracer_name ) const {
714 if (m != opt::tracer)
715 throw std::logic_error("Logic error - should be called with tracer argument");
716
717 return this->tracer.at(tracer_name);
718 }
719
720 inline double& Rates::get_ref( opt m ) {
721 return const_cast< double& >(
722 static_cast< const Rates* >( this )->get_ref( m )
723 );
724 }
725
726 inline double& Rates::get_ref( opt m, const std::string& tracer_name ) {
727 if (m == opt::tracer) this->tracer.emplace(tracer_name, 0.0);
728 return this->tracer.at(tracer_name);
729 }
730
731 void Rates::init_json(Json::JsonObject& json_data) const {
732
733 if (this->has(opt::wat))
734 json_data.add_item("wat", this->get(opt::wat));
735
736 if (this->has(opt::oil))
737 json_data.add_item("oil", this->get(opt::oil));
738
739 if (this->has(opt::gas))
740 json_data.add_item("gas", this->get(opt::gas));
741
742 }
743
744 bool inline Rates::flowing() const {
745 return ((this->wat != 0) ||
746 (this->oil != 0) ||
747 (this->gas != 0));
748 }
749
750 inline bool Well::flowing() const noexcept {
751 return this->rates.flowing();
752 }
753
754 template <class MessageBufferType>
755 void Rates::write(MessageBufferType& buffer) const {
756 buffer.write(this->mask);
757 buffer.write(this->wat);
758 buffer.write(this->oil);
759 buffer.write(this->gas);
760 buffer.write(this->polymer);
761 buffer.write(this->solvent);
762 buffer.write(this->energy);
763 buffer.write(this->dissolved_gas);
764 buffer.write(this->vaporized_oil);
765 buffer.write(this->reservoir_water);
766 buffer.write(this->reservoir_oil);
767 buffer.write(this->reservoir_gas);
768 buffer.write(this->productivity_index_water);
769 buffer.write(this->productivity_index_oil);
770 buffer.write(this->productivity_index_gas);
771 buffer.write(this->well_potential_water);
772 buffer.write(this->well_potential_oil);
773 buffer.write(this->well_potential_gas);
774 buffer.write(this->brine);
775 buffer.write(this->alq);
776 //tracer:
777 unsigned int size = this->tracer.size();
778 buffer.write(size);
779 for (const auto& [name, rate] : this->tracer) {
780 buffer.write(name);
781 buffer.write(rate);
782 }
783 buffer.write(this->micp);
784 buffer.write(this->vaporized_water);
785 }
786
787 template <class MessageBufferType>
788 void Connection::write(MessageBufferType& buffer) const {
789 buffer.write(this->index);
790 this->rates.write(buffer);
791 buffer.write(this->pressure);
792 buffer.write(this->reservoir_rate);
793 buffer.write(this->cell_pressure);
794 buffer.write(this->cell_saturation_water);
795 buffer.write(this->cell_saturation_gas);
796 buffer.write(this->effective_Kh);
797 buffer.write(this->trans_factor);
798 }
799
800
801 void Connection::init_json(Json::JsonObject& json_data) const {
802 auto json_rates = json_data.add_object("rates");
803 this->rates.init_json(json_rates);
804
805 json_data.add_item("global_index", static_cast<int>(this->index));
806 json_data.add_item("pressure", this->pressure);
807 json_data.add_item("reservoir_rate", this->reservoir_rate);
808 json_data.add_item("cell_pressure", this->cell_pressure);
809 json_data.add_item("swat", this->cell_saturation_water);
810 json_data.add_item("sgas", this->cell_saturation_gas);
811 json_data.add_item("Kh", this->effective_Kh);
812 json_data.add_item("trans_factor", this->trans_factor);
813 }
814
815 template <class MessageBufferType>
816 void Segment::write(MessageBufferType& buffer) const {
817 buffer.write(this->segNumber);
818 this->rates.write(buffer);
819 this->pressures.write(buffer);
820 }
821
822 template <class MessageBufferType>
823 void CurrentControl::write(MessageBufferType& buffer) const
824 {
825 buffer.write(this->isProducer);
826 if (this->isProducer) {
827 buffer.write(this->prod);
828 }
829 else {
830 buffer.write(this->inj);
831 }
832 }
833
834 template <class MessageBufferType>
835 void Well::write(MessageBufferType& buffer) const {
836 this->rates.write(buffer);
837 buffer.write(this->bhp);
838 buffer.write(this->thp);
839 buffer.write(this->temperature);
840 buffer.write(this->control);
841
842 {
843 const auto status = ::Opm::Well::Status2String(this->dynamicStatus);
844 buffer.write(status);
845 }
846
847 unsigned int size = this->connections.size();
848 buffer.write(size);
849 for (const Connection& comp : this->connections)
850 comp.write(buffer);
851
852 {
853 const auto nSeg =
854 static_cast<unsigned int>(this->segments.size());
855 buffer.write(nSeg);
856
857 for (const auto& seg : this->segments) {
858 seg.second.write(buffer);
859 }
860 }
861
862 this->current_control.write(buffer);
863 this->guide_rates.write(buffer);
864 }
865
866 template <class MessageBufferType>
867 void Rates::read(MessageBufferType& buffer) {
868 buffer.read(this->mask);
869 buffer.read(this->wat);
870 buffer.read(this->oil);
871 buffer.read(this->gas);
872 buffer.read(this->polymer);
873 buffer.read(this->solvent);
874 buffer.read(this->energy);
875 buffer.read(this->dissolved_gas);
876 buffer.read(this->vaporized_oil);
877 buffer.read(this->reservoir_water);
878 buffer.read(this->reservoir_oil);
879 buffer.read(this->reservoir_gas);
880 buffer.read(this->productivity_index_water);
881 buffer.read(this->productivity_index_oil);
882 buffer.read(this->productivity_index_gas);
883 buffer.read(this->well_potential_water);
884 buffer.read(this->well_potential_oil);
885 buffer.read(this->well_potential_gas);
886 buffer.read(this->brine);
887 buffer.read(this->alq);
888 //tracer:
889 unsigned int size;
890 buffer.read(size);
891 for (size_t i = 0; i < size; ++i) {
892 std::string tracer_name;
893 buffer.read(tracer_name);
894 double tracer_rate;
895 buffer.read(tracer_rate);
896 this->tracer.emplace(tracer_name, tracer_rate);
897 }
898 buffer.read(this->micp);
899 buffer.read(this->vaporized_water);
900 }
901
902 template <class MessageBufferType>
903 void Connection::read(MessageBufferType& buffer) {
904 buffer.read(this->index);
905 this->rates.read(buffer);
906 buffer.read(this->pressure);
907 buffer.read(this->reservoir_rate);
908 buffer.read(this->cell_pressure);
909 buffer.read(this->cell_saturation_water);
910 buffer.read(this->cell_saturation_gas);
911 buffer.read(this->effective_Kh);
912 buffer.read(this->trans_factor);
913 }
914
915 template <class MessageBufferType>
916 void Segment::read(MessageBufferType& buffer) {
917 buffer.read(this->segNumber);
918 this->rates.read(buffer);
919 this->pressures.read(buffer);
920 }
921
922 template <class MessageBufferType>
923 void CurrentControl::read(MessageBufferType& buffer)
924 {
925 buffer.read(this->isProducer);
926 if (this->isProducer) {
927 buffer.read(this->prod);
928 }
929 else {
930 buffer.read(this->inj);
931 }
932 }
933
934 template <class MessageBufferType>
935 void Well::read(MessageBufferType& buffer) {
936 this->rates.read(buffer);
937 buffer.read(this->bhp);
938 buffer.read(this->thp);
939 buffer.read(this->temperature);
940 buffer.read(this->control);
941
942 {
943 auto status = std::string{};
944 buffer.read(status);
945 this->dynamicStatus = ::Opm::Well::StatusFromString(status);
946 }
947
948 // Connection information
949 unsigned int size = 0.0; //this->connections.size();
950 buffer.read(size);
951 this->connections.resize(size);
952 for (size_t i = 0; i < size; ++i)
953 {
954 auto& comp = this->connections[ i ];
955 comp.read(buffer);
956 }
957
958 // Segment information (if applicable)
959 const auto nSeg = [&buffer]() -> unsigned int
960 {
961 auto n = 0u;
962 buffer.read(n);
963
964 return n;
965 }();
966
967 for (auto segID = 0*nSeg; segID < nSeg; ++segID) {
968 auto seg = Segment{};
969 seg.read(buffer);
970
971 const auto segNumber = seg.segNumber;
972 this->segments.emplace(segNumber, std::move(seg));
973 }
974
975 this->current_control.read(buffer);
976 this->guide_rates.read(buffer);
977 }
978
979 void Well::init_json(Json::JsonObject& json_data) const {
980 auto json_connections = json_data.add_array("connections");
981 for (const auto& conn : this->connections) {
982 auto json_conn = json_connections.add_object();
983 conn.init_json(json_conn);
984 }
985 auto json_rates = json_data.add_object("rates");
986 this->rates.init_json(json_rates);
987
988 json_data.add_item("bhp", this->bhp);
989 json_data.add_item("thp", this->thp);
990 json_data.add_item("temperature", this->temperature);
991 json_data.add_item("status", ::Opm::Well::Status2String(this->dynamicStatus));
992
993 auto json_control = json_data.add_object("control");
994 this->current_control.init_json(json_control);
995
996 auto json_guiderate = json_data.add_object("guiderate");
997 this->guide_rates.init_json(json_guiderate);
998 }
999
1000}} // Opm::data
1001
1002#endif //OPM_OUTPUT_WELLS_HPP
Definition: JsonObject.hpp:32
Class for (de-)serializing.
Definition: Serializer.hpp:75
Definition: GuideRateValue.hpp:32
Definition: Wells.hpp:41
bool flowing() const
Returns true if any of the rates oil, gas, water is nonzero.
Definition: Wells.hpp:744
double get(opt m) const
Read the value indicated by m.
Definition: Wells.hpp:597
Rates & set(opt m, double value)
Set the value specified by m.
Definition: Wells.hpp:618
bool has(opt) const
Query if a value is set.
Definition: Wells.hpp:590
Definition: Wells.hpp:253
Definition: Wells.hpp:500
This class implements a small container which holds the transmissibility mulitpliers for all the face...
Definition: Exceptions.hpp:29
Definition: Wells.hpp:197
Definition: Wells.hpp:354
Definition: Wells.hpp:319
Definition: Wells.hpp:408