My Project
Loading...
Searching...
No Matches
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 <opm/output/data/GuideRateValue.hpp>
24#include <opm/input/eclipse/Schedule/Well/WellEnums.hpp>
25
26#include <opm/json/JsonObject.hpp>
27
28#include <algorithm>
29#include <array>
30#include <climits>
31#include <cstddef>
32#include <map>
33#include <stdexcept>
34#include <string>
35#include <type_traits>
36#include <unordered_map>
37#include <vector>
38
39namespace Opm { 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 microbial = (1 << 20),
75 oxygen = (1 << 21),
76 urea = (1 << 22),
77 vaporized_water = (1 << 23),
78 mass_gas = (1 << 24)
79 };
80
81 using enum_size = std::underlying_type< opt >::type;
82
84 inline bool has( opt ) const;
85
88 inline double get( opt m ) const;
91 inline double get( opt m, double default_value ) const;
92 inline double get( opt m, double default_value , const std::string& tracer_name ) const;
96 inline Rates& set( opt m, double value );
97 inline Rates& set( opt m, double value , const std::string& tracer_name );
98
100 inline bool flowing() const;
101
102 template <class MessageBufferType>
103 void write(MessageBufferType& buffer) const;
104 template <class MessageBufferType>
105 void read(MessageBufferType& buffer);
106
107 bool operator==(const Rates& rat2) const;
108
109 inline void init_json(Json::JsonObject& json_data) const;
110
111 template<class Serializer>
112 void serializeOp(Serializer& serializer)
113 {
114 serializer(mask);
115 serializer(wat);
116 serializer(oil);
117 serializer(gas);
118 serializer(polymer);
119 serializer(solvent);
120 serializer(energy);
121 serializer(dissolved_gas);
122 serializer(vaporized_oil);
123 serializer(reservoir_water);
124 serializer(reservoir_oil);
125 serializer(reservoir_gas);
126 serializer(productivity_index_water);
127 serializer(productivity_index_oil);
128 serializer(productivity_index_gas);
129 serializer(well_potential_water);
130 serializer(well_potential_oil);
131 serializer(well_potential_gas);
132 serializer(brine);
133 serializer(alq);
134 serializer(tracer);
135 serializer(microbial);
136 serializer(oxygen);
137 serializer(urea);
138 serializer(vaporized_water);
139 serializer(mass_gas);
140 }
141
142 static Rates serializationTestObject()
143 {
144 Rates rat1;
145 rat1.set(opt::wat, 1.0);
146 rat1.set(opt::oil, 2.0);
147 rat1.set(opt::gas, 3.0);
148 rat1.set(opt::polymer, 4.0);
149 rat1.set(opt::solvent, 5.0);
150 rat1.set(opt::energy, 6.0);
151 rat1.set(opt::dissolved_gas, 7.0);
152 rat1.set(opt::vaporized_oil, 8.0);
153 rat1.set(opt::reservoir_water, 9.0);
154 rat1.set(opt::reservoir_oil, 10.0);
155 rat1.set(opt::reservoir_gas, 11.0);
156 rat1.set(opt::productivity_index_water, 12.0);
157 rat1.set(opt::productivity_index_oil, 13.0);
158 rat1.set(opt::productivity_index_gas, 14.0);
159 rat1.set(opt::well_potential_water, 15.0);
160 rat1.set(opt::well_potential_oil, 16.0);
161 rat1.set(opt::well_potential_gas, 17.0);
162 rat1.set(opt::brine, 18.0);
163 rat1.set(opt::alq, 19.0);
164 rat1.set(opt::microbial, 20.0);
165 rat1.set(opt::oxygen, 21.0);
166 rat1.set(opt::urea, 22.0);
167 rat1.set(opt::vaporized_water, 23.0);
168 rat1.set(opt::mass_gas, 24.0);
169 rat1.tracer.insert({"test_tracer", 1.0});
170
171 return rat1;
172 }
173
174 private:
175 double& get_ref( opt );
176 double& get_ref( opt, const std::string& tracer_name );
177 const double& get_ref( opt ) const;
178 const double& get_ref( opt, const std::string& tracer_name ) const;
179
180 opt mask = static_cast< opt >( 0 );
181
182 double wat = 0.0;
183 double oil = 0.0;
184 double gas = 0.0;
185 double polymer = 0.0;
186 double solvent = 0.0;
187 double energy = 0.0;
188 double dissolved_gas = 0.0;
189 double vaporized_oil = 0.0;
190 double reservoir_water = 0.0;
191 double reservoir_oil = 0.0;
192 double reservoir_gas = 0.0;
193 double productivity_index_water = 0.0;
194 double productivity_index_oil = 0.0;
195 double productivity_index_gas = 0.0;
196 double well_potential_water = 0.0;
197 double well_potential_oil = 0.0;
198 double well_potential_gas = 0.0;
199 double brine = 0.0;
200 double alq = 0.0;
201 std::map<std::string, double> tracer{};
202 double microbial = 0.0;
203 double oxygen = 0.0;
204 double urea = 0.0;
205 double vaporized_water = 0.0;
206 double mass_gas = 0.0;
207 };
208
210 {
211 double rate;
212 double total;
213 double skin_factor;
214 double thickness;
215 double perm;
216 double poro;
217 double radius;
218 double area_of_flow;
219
220 template<class Serializer>
221 void serializeOp(Serializer& serializer) {
222 serializer(rate);
223 serializer(total);
224 serializer(skin_factor);
225 serializer(thickness);
226 serializer(perm);
227 serializer(poro);
228 serializer(radius);
229 serializer(area_of_flow);
230 }
231
232 bool operator==(const ConnectionFiltrate& filtrate) const
233 {
234 return this->rate == filtrate.rate &&
235 this->total == filtrate.total &&
236 this->skin_factor == filtrate.skin_factor &&
237 this->thickness == filtrate.thickness &&
238 this->perm == filtrate.perm &&
239 this->poro == filtrate.poro &&
240 this->radius == filtrate.radius &&
241 this->area_of_flow == filtrate.area_of_flow;
242 }
243
244 static ConnectionFiltrate serializationTestObject()
245 {
246 return {0.8, 100., -1., 2., 1.e-9,
247 0.3, 0.05, 0.8};
248 }
249
250 template <class MessageBufferType>
251 void write(MessageBufferType& buffer) const;
252
253 template <class MessageBufferType>
254 void read(MessageBufferType& buffer);
255 };
256
259 {
262 {
264 double avg{};
265
267 double max{};
268
270 double min{};
271
275 double stdev{};
276
279 {
280 return {
281 12.34, 56.78, 9.10, 11.12
282 };
283 }
284
290 template <class Serializer>
291 void serializeOp(Serializer& serializer)
292 {
293 serializer(this->avg);
294 serializer(this->max);
295 serializer(this->min);
296 serializer(this->stdev);
297 }
298
306 bool operator==(const Statistics& that) const
307 {
308 return (this->avg == that.avg)
309 && (this->max == that.max)
310 && (this->min == that.min)
311 && (this->stdev == that.stdev)
312 ;
313 }
314
316 template <class MessageBufferType>
317 void write(MessageBufferType& buffer) const
318 {
319 buffer.write(this->avg);
320 buffer.write(this->max);
321 buffer.write(this->min);
322 buffer.write(this->stdev);
323 }
324
326 template <class MessageBufferType>
327 void read(MessageBufferType& buffer)
328 {
329 buffer.read(this->avg);
330 buffer.read(this->max);
331 buffer.read(this->min);
332 buffer.read(this->stdev);
333 }
334 };
335
339 std::size_t numCells{};
340
343
346
349
352 {
353 auto fract = ConnectionFracturing{};
354
355 fract.numCells = 123;
359
360 return fract;
361 }
362
368 template <class Serializer>
369 void serializeOp(Serializer& serializer)
370 {
371 serializer(this->numCells);
372 serializer(this->press);
373 serializer(this->rate);
374 serializer(this->width);
375 }
376
384 bool operator==(const ConnectionFracturing& that) const
385 {
386 return (this->numCells == that.numCells)
387 && (this->press == that.press)
388 && (this->rate == that.rate)
389 && (this->width == that.width)
390 ;
391 }
392
394 template <class MessageBufferType>
395 void write(MessageBufferType& buffer) const
396 {
397 buffer.write(this->numCells);
398 buffer.write(this->press);
399 buffer.write(this->rate);
400 buffer.write(this->width);
401 }
402
404 template <class MessageBufferType>
405 void read(MessageBufferType& buffer)
406 {
407 buffer.read(this->numCells);
408 buffer.read(this->press);
409 buffer.read(this->rate);
410 buffer.read(this->width);
411 }
412 };
413
415 {
416 using global_index = std::size_t;
417 static const constexpr int restart_size = 6;
418
419 global_index index{};
420 Rates rates{};
421 double pressure{};
422 double reservoir_rate{};
423 double cell_pressure{};
424 double cell_saturation_water{};
425 double cell_saturation_gas{};
426 double effective_Kh{};
427 double trans_factor{};
428 double d_factor{};
429 double compact_mult{1.0}; // Rock compaction transmissibility multiplier (ROCKTAB)
430
431 ConnectionFiltrate filtrate{};
432
435
436 bool operator==(const Connection& conn2) const
437 {
438 return (index == conn2.index)
439 && (rates == conn2.rates)
440 && (pressure == conn2.pressure)
441 && (reservoir_rate == conn2.reservoir_rate)
442 && (cell_pressure == conn2.cell_pressure)
443 && (cell_saturation_water == conn2.cell_saturation_water)
444 && (cell_saturation_gas == conn2.cell_saturation_gas)
445 && (effective_Kh == conn2.effective_Kh)
446 && (trans_factor == conn2.trans_factor)
447 && (d_factor == conn2.d_factor)
448 && (compact_mult == conn2.compact_mult)
449 && (filtrate == conn2.filtrate)
450 && (this->fract == conn2.fract)
451 ;
452 }
453
454 template <class MessageBufferType>
455 void write(MessageBufferType& buffer) const;
456 template <class MessageBufferType>
457 void read(MessageBufferType& buffer);
458
459 inline void init_json(Json::JsonObject& json_data) const;
460
461 template<class Serializer>
462 void serializeOp(Serializer& serializer)
463 {
464 serializer(index);
465 serializer(rates);
466 serializer(pressure);
467 serializer(reservoir_rate);
468 serializer(cell_pressure);
469 serializer(cell_saturation_water);
470 serializer(cell_saturation_gas);
471 serializer(effective_Kh);
472 serializer(trans_factor);
473 serializer(d_factor);
474 serializer(compact_mult);
475 serializer(filtrate);
476 serializer(this->fract);
477 }
478
479 static Connection serializationTestObject()
480 {
481 return Connection {
482 1, Rates::serializationTestObject(),
483 2.0, 3.0, 4.0, 5.0,
484 6.0, 7.0, 8.0, 9.0, 0.987,
485 ConnectionFiltrate::serializationTestObject(),
487 };
488 }
489 };
490
492 {
493 public:
494 enum class Value : std::size_t {
495 Pressure, PDrop, PDropHydrostatic, PDropAccel, PDropFriction,
496 };
497
498 double& operator[](const Value i)
499 {
500 return this->values_[this->index(i)];
501 }
502
503 double operator[](const Value i) const
504 {
505 return this->values_[this->index(i)];
506 }
507
508 bool operator==(const SegmentPressures& segpres2) const
509 {
510 return this->values_ == segpres2.values_;
511 }
512
513 template <class MessageBufferType>
514 void write(MessageBufferType& buffer) const
515 {
516 for (const auto& value : this->values_) {
517 buffer.write(value);
518 }
519 }
520
521 template <class MessageBufferType>
522 void read(MessageBufferType& buffer)
523 {
524 for (auto& value : this->values_) {
525 buffer.read(value);
526 }
527 }
528
529 template<class Serializer>
530 void serializeOp(Serializer& serializer)
531 {
532 serializer(values_);
533 }
534
535 static SegmentPressures serializationTestObject()
536 {
537 SegmentPressures spres;
538 spres[Value::Pressure] = 1.0;
539 spres[Value::PDrop] = 2.0;
540 spres[Value::PDropHydrostatic] = 3.0;
541 spres[Value::PDropAccel] = 4.0;
542 spres[Value::PDropFriction] = 5.0;
543
544 return spres;
545 }
546
547 private:
548 constexpr static std::size_t numvals = 5;
549
550 std::array<double, numvals> values_ = {0};
551
552 std::size_t index(const Value ix) const
553 {
554 return static_cast<std::size_t>(ix);
555 }
556 };
557
558 template <typename Items>
560 {
561 public:
562 using Item = typename Items::Item;
563
564 void clear()
565 {
566 this->has_ = static_cast<unsigned char>(0);
567 this->value_.fill(0.0);
568 }
569
570 constexpr bool has(const Item p) const
571 {
572 const auto i = this->index(p);
573
574 return (i < Size) && this->hasItem(i);
575 }
576
577 bool operator==(const QuantityCollection& that) const
578 {
579 return (this->has_ == that.has_)
580 && (this->value_ == that.value_);
581 }
582
583 double get(const Item p) const
584 {
585 if (! this->has(p)) {
586 throw std::invalid_argument {
587 "Request for Unset Item Value for " + Items::itemName(p)
588 };
589 }
590
591 return this->value_[ this->index(p) ];
592 }
593
594 QuantityCollection& set(const Item p, const double value)
595 {
596 const auto i = this->index(p);
597
598 if (i >= Size) {
599 throw std::invalid_argument {
600 "Cannot Assign Item Value for Unsupported Item '"
601 + Items::itemName(p) + '\''
602 };
603 }
604
605 this->has_ |= 1 << i;
606 this->value_[i] = value;
607
608 return *this;
609 }
610
611 template <class MessageBufferType>
612 void write(MessageBufferType& buffer) const
613 {
614 buffer.write(this->has_);
615
616 for (const auto& x : this->value_) {
617 buffer.write(x);
618 }
619 }
620
621 template <class MessageBufferType>
622 void read(MessageBufferType& buffer)
623 {
624 this->clear();
625 buffer.read(this->has_);
626
627 for (auto& x : this->value_) {
628 buffer.read(x);
629 }
630 }
631
632 template <class Serializer>
633 void serializeOp(Serializer& serializer)
634 {
635 serializer(this->has_);
636 serializer(this->value_);
637 }
638
639 static QuantityCollection serializationTestObject()
640 {
641 auto quant = QuantityCollection{};
642
643 for (const auto& [item, value] : Items::serializationTestItems()) {
644 quant.set(item, value);
645 }
646
647 return quant;
648 }
649
650 private:
651 enum { Size = static_cast<std::size_t>(Item::NumItems) };
652
653 static_assert(Size <= static_cast<std::size_t>(CHAR_BIT),
654 "Number of items must not exceed CHAR_BIT");
655
658 unsigned char has_{};
659
661 std::array<double, Size> value_{};
662
663 constexpr std::size_t index(const Item p) const noexcept
664 {
665 return static_cast<std::size_t>(p);
666 }
667
668 bool hasItem(const std::size_t i) const
669 {
670 return (this->has_ & (1 << i)) != 0;
671 }
672 };
673
675 {
676 enum class Item {
677 Oil, Gas, Water,
678
679 // -- Must be last enumerator --
680 NumItems,
681 };
682
683 static std::string itemName(const Item p)
684 {
685 switch (p) {
686 case Item::Oil: return "Oil";
687 case Item::Gas: return "Gas";
688 case Item::Water: return "Water";
689
690 case Item::NumItems:
691 return "Out of bounds (NumItems)";
692 }
693
694 return "Unknown (" + std::to_string(static_cast<int>(p)) + ')';
695 }
696
697 static auto serializationTestItems()
698 {
699 return std::vector {
700 std::pair { Item::Oil , 1.0 },
701 std::pair { Item::Gas , 7.0 },
702 std::pair { Item::Water, 2.9 },
703 };
704 }
705 };
706
708 {
709 enum class Item {
710 Oil, Gas, Water, Mixture, MixtureWithExponents,
711
712 // -- Must be last enumerator --
713 NumItems,
714 };
715
716 static std::string itemName(const Item p)
717 {
718 switch (p) {
719 case Item::Oil: return "Oil";
720 case Item::Gas: return "Gas";
721 case Item::Water: return "Water";
722 case Item::Mixture: return "Mixture";
723 case Item::MixtureWithExponents: return "MixtureWithExponents";
724
725 case Item::NumItems:
726 return "Out of bounds (NumItems)";
727 }
728
729 return "Unknown (" + std::to_string(static_cast<int>(p)) + ')';
730 }
731
732 static auto serializationTestItems()
733 {
734 return std::vector {
735 std::pair { Item::Oil , 876.54 },
736 std::pair { Item::Gas , 321.09 },
737 std::pair { Item::Water , 987.65 },
738 std::pair { Item::Mixture , 975.31 },
739 std::pair { Item::MixtureWithExponents, 765.43 },
740 };
741 }
742 };
743
746
747 struct Segment
748 {
749 Rates rates{};
750 SegmentPressures pressures{};
751 SegmentPhaseQuantity velocity{};
752 SegmentPhaseQuantity holdup{};
753 SegmentPhaseQuantity viscosity{};
754 SegmentPhaseDensity density{};
755 std::size_t segNumber{};
756
757 bool operator==(const Segment& seg2) const
758 {
759 return (rates == seg2.rates)
760 && (pressures == seg2.pressures)
761 && (velocity == seg2.velocity)
762 && (holdup == seg2.holdup)
763 && (viscosity == seg2.viscosity)
764 && (density == seg2.density)
765 && (segNumber == seg2.segNumber);
766 }
767
768 template <class MessageBufferType>
769 void write(MessageBufferType& buffer) const;
770
771 template <class MessageBufferType>
772 void read(MessageBufferType& buffer);
773
774 template <class Serializer>
775 void serializeOp(Serializer& serializer)
776 {
777 serializer(this->rates);
778 serializer(this->pressures);
779 serializer(this->velocity);
780 serializer(this->holdup);
781 serializer(this->viscosity);
782 serializer(this->density);
783 serializer(this->segNumber);
784 }
785
786 static Segment serializationTestObject()
787 {
788 return {
789 Rates::serializationTestObject(),
790 SegmentPressures::serializationTestObject(),
791 SegmentPhaseQuantity::serializationTestObject(), // velocity
792 SegmentPhaseQuantity::serializationTestObject(), // holdup
793 SegmentPhaseQuantity::serializationTestObject(), // viscosity
794 SegmentPhaseDensity::serializationTestObject(), // density
795 10
796 };
797 }
798 };
799
801 {
802 bool isProducer{true};
803
804 ::Opm::WellProducerCMode prod {
805 ::Opm::WellProducerCMode::CMODE_UNDEFINED
806 };
807
808 ::Opm::WellInjectorCMode inj {
809 ::Opm::WellInjectorCMode::CMODE_UNDEFINED
810 };
811
812 bool operator==(const CurrentControl& rhs) const
813 {
814 return (this->isProducer == rhs.isProducer)
815 && ((this->isProducer && (this->prod == rhs.prod)) ||
816 (!this->isProducer && (this->inj == rhs.inj)));
817 }
818
819 void init_json(Json::JsonObject& json_data) const
820 {
821 if (this->inj == ::Opm::WellInjectorCMode::CMODE_UNDEFINED)
822 json_data.add_item("inj", "CMODE_UNDEFINED");
823 else
824 json_data.add_item("inj", ::Opm::WellInjectorCMode2String(this->inj));
825
826 if (this->prod == ::Opm::WellProducerCMode::CMODE_UNDEFINED)
827 json_data.add_item("prod", "CMODE_UNDEFINED");
828 else
829 json_data.add_item("prod", ::Opm::WellProducerCMode2String(this->prod));
830 }
831
832 template <class MessageBufferType>
833 void write(MessageBufferType& buffer) const;
834
835 template <class MessageBufferType>
836 void read(MessageBufferType& buffer);
837
838 template<class Serializer>
839 void serializeOp(Serializer& serializer)
840 {
841 serializer(isProducer);
842 serializer(prod);
843 serializer(inj);
844 }
845
846 static CurrentControl serializationTestObject()
847 {
848 return CurrentControl{false,
849 ::Opm::WellProducerCMode::BHP,
850 ::Opm::WellInjectorCMode::GRUP
851 };
852 }
853 };
854
856 {
857 public:
858 enum class Quantity { WBP, WBP4, WBP5, WBP9 };
859
860 double& operator[](const Quantity q)
861 {
862 return this->wbp_[static_cast<std::size_t>(q)];
863 }
864
865 double operator[](const Quantity q) const
866 {
867 return this->wbp_[static_cast<std::size_t>(q)];
868 }
869
870 bool operator==(const WellBlockAvgPress& that) const
871 {
872 return this->wbp_ == that.wbp_;
873 }
874
875 template <class MessageBufferType>
876 void write(MessageBufferType& buffer) const;
877
878 template <class MessageBufferType>
879 void read(MessageBufferType& buffer);
880
881 template <class Serializer>
882 void serializeOp(Serializer& serializer)
883 {
884 serializer(this->wbp_);
885 }
886
887 static WellBlockAvgPress serializationTestObject()
888 {
889 auto wbp = WellBlockAvgPress{};
890
891 wbp[Quantity::WBP] = 17.29;
892 wbp[Quantity::WBP4] = 2.718;
893 wbp[Quantity::WBP5] = 3.1415;
894 wbp[Quantity::WBP9] = 1.618;
895
896 return wbp;
897 }
898
899 private:
900 static constexpr auto NumQuantities =
901 static_cast<std::size_t>(Quantity::WBP9) + 1;
902
903 std::array<double, NumQuantities> wbp_{};
904 };
905
907 {
908 double rate{0.};
909 double total{0.};
910 double concentration{0.};
911
912 template<class Serializer>
913 void serializeOp(Serializer& serializer) {
914 serializer(rate);
915 serializer(total);
916 serializer(concentration);
917 }
918
919 bool operator==(const WellFiltrate& filtrate) const {
920 return this->rate == filtrate.rate
921 && this->total == filtrate.total
922 && this->concentration == filtrate.concentration;
923 }
924
925 static WellFiltrate serializationTestObject() {
926 WellFiltrate res;
927 res.rate = 1.;
928 res.total = 10.;
929 res.concentration = 0.;
930 return res;
931 }
932
933 template <class MessageBufferType>
934 void write(MessageBufferType& buffer) const;
935
936 template <class MessageBufferType>
937 void read(MessageBufferType& buffer);
938 };
939
941 {
942 enum class Item {
943 Bhp, OilRate, WaterRate, GasRate, ResVRate, LiquidRate,
944
945 // -- Must be last enumerator --
946 NumItems,
947 };
948
949 static std::string itemName(const Item p)
950 {
951 switch (p) {
952 case Item::Bhp: return "Bhp";
953 case Item::OilRate: return "OilRate";
954 case Item::WaterRate: return "WaterRate";
955 case Item::GasRate: return "GasRate";
956 case Item::ResVRate: return "ResVRate";
957 case Item::LiquidRate: return "LiquidRate";
958
959 case Item::NumItems:
960 return "Out of bounds (NumItems)";
961 }
962
963 return "Unknown (" + std::to_string(static_cast<int>(p)) + ')';
964 }
965
966 static auto serializationTestItems()
967 {
968 return std::vector {
969 std::pair { Item::Bhp , 321.09 },
970 std::pair { Item::OilRate , 987.65 },
971 std::pair { Item::WaterRate , 975.31 },
972 std::pair { Item::GasRate , 765.43 },
973 std::pair { Item::ResVRate , 876.54 },
974 std::pair { Item::LiquidRate, 54.32 },
975 };
976 }
977 };
978
980
981 struct Well
982 {
983 Rates rates{};
984
985 double bhp{0.0};
986 double thp{0.0};
987 double temperature{0.0};
988 int control{0};
989 double efficiency_scaling_factor{1.0};
990
991 WellFiltrate filtrate;
992
993 ::Opm::WellStatus dynamicStatus { Opm::WellStatus::OPEN };
994
995 std::vector<Connection> connections{};
996 std::unordered_map<std::size_t, Segment> segments{};
997 CurrentControl current_control{};
998 GuideRateValue guide_rates{};
999 WellControlLimits limits{};
1000
1001 inline bool flowing() const noexcept;
1002
1003 template <class MessageBufferType>
1004 void write(MessageBufferType& buffer) const;
1005
1006 template <class MessageBufferType>
1007 void read(MessageBufferType& buffer);
1008
1009 inline void init_json(Json::JsonObject& json_data) const;
1010
1011 const Connection*
1012 find_connection(const Connection::global_index connection_grid_index) const
1013 {
1014 auto connection = std::find_if(this->connections.begin(),
1015 this->connections.end(),
1016 [connection_grid_index](const Connection& c)
1017 { return c.index == connection_grid_index; });
1018
1019 if (connection == this->connections.end()) {
1020 return nullptr;
1021 }
1022
1023 return &*connection;
1024 }
1025
1026 Connection*
1027 find_connection(const Connection::global_index connection_grid_index)
1028 {
1029 auto connection = std::find_if(this->connections.begin(),
1030 this->connections.end(),
1031 [connection_grid_index](const Connection& c)
1032 { return c.index == connection_grid_index; });
1033
1034 if (connection == this->connections.end()) {
1035 return nullptr;
1036 }
1037
1038 return &*connection;
1039 }
1040
1041 bool operator==(const Well& well2) const
1042 {
1043 return (this->rates == well2.rates)
1044 && (this->bhp == well2.bhp)
1045 && (this->thp == well2.thp)
1046 && (this->temperature == well2.temperature)
1047 && (this->filtrate == well2.filtrate)
1048 && (this->control == well2.control)
1049 && (this->dynamicStatus == well2.dynamicStatus)
1050 && (this->connections == well2.connections)
1051 && (this->segments == well2.segments)
1052 && (this->current_control == well2.current_control)
1053 && (this->guide_rates == well2.guide_rates)
1054 && (this->limits == well2.limits)
1055 ;
1056 }
1057
1058 template<class Serializer>
1059 void serializeOp(Serializer& serializer)
1060 {
1061 serializer(rates);
1062 serializer(bhp);
1063 serializer(thp);
1064 serializer(temperature);
1065 serializer(control);
1066 serializer(efficiency_scaling_factor);
1067 serializer(filtrate);
1068 serializer(dynamicStatus);
1069 serializer(connections);
1070 serializer(segments);
1071 serializer(current_control);
1072 serializer(guide_rates);
1073 serializer(limits);
1074 }
1075
1076 static Well serializationTestObject()
1077 {
1078 return Well {
1079 Rates::serializationTestObject(),
1080 1.0,
1081 2.0,
1082 3.0,
1083 4,
1084 5.0,
1085 WellFiltrate::serializationTestObject(),
1086 ::Opm::WellStatus::SHUT,
1087 {Connection::serializationTestObject()},
1088 {{0, Segment::serializationTestObject()}},
1089 CurrentControl::serializationTestObject(),
1090 GuideRateValue::serializationTestObject(),
1091 WellControlLimits::serializationTestObject()
1092 };
1093 }
1094 };
1095
1096 class Wells: public std::map<std::string , Well> {
1097 public:
1098
1099 double get(const std::string& well_name , Rates::opt m) const {
1100 const auto& well = this->find( well_name );
1101 if( well == this->end() ) return 0.0;
1102
1103 return well->second.rates.get( m, 0.0 );
1104 }
1105
1106 double get(const std::string& well_name , Rates::opt m, const std::string& tracer_name) const {
1107 const auto& well = this->find( well_name );
1108 if( well == this->end() ) return 0.0;
1109
1110 return well->second.rates.get( m, 0.0, tracer_name);
1111 }
1112
1113 double get(const std::string& well_name , Connection::global_index connection_grid_index, Rates::opt m) const {
1114 const auto& witr = this->find( well_name );
1115 if( witr == this->end() ) return 0.0;
1116
1117 const auto& well = witr->second;
1118 const auto& connection = std::find_if( well.connections.begin() ,
1119 well.connections.end() ,
1120 [=]( const Connection& c ) {
1121 return c.index == connection_grid_index; });
1122
1123 if( connection == well.connections.end() )
1124 return 0.0;
1125
1126 return connection->rates.get( m, 0.0 );
1127 }
1128
1129 template <class MessageBufferType>
1130 void write(MessageBufferType& buffer) const {
1131 unsigned int size = this->size();
1132 buffer.write(size);
1133 for (const auto& witr : *this) {
1134 const std::string& name = witr.first;
1135 buffer.write(name);
1136 const Well& well = witr.second;
1137 well.write(buffer);
1138 }
1139 }
1140
1141 template <class MessageBufferType>
1142 void read(MessageBufferType& buffer) {
1143 unsigned int size;
1144 buffer.read(size);
1145 for (size_t i = 0; i < size; ++i) {
1146 std::string name;
1147 buffer.read(name);
1148 Well well;
1149 well.read(buffer);
1150 this->emplace(name, well);
1151 }
1152 }
1153
1154 void init_json(Json::JsonObject& json_data) const {
1155 for (const auto& [wname, well] : *this) {
1156 auto json_well = json_data.add_object(wname);
1157 well.init_json(json_well);
1158 }
1159 }
1160
1161
1162 Json::JsonObject json() const {
1163 Json::JsonObject json_data;
1164 this->init_json(json_data);
1165 return json_data;
1166 }
1167
1168 template<class Serializer>
1169 void serializeOp(Serializer& serializer)
1170 {
1171 serializer(static_cast<std::map<std::string,Well>&>(*this));
1172 }
1173
1174 static Wells serializationTestObject()
1175 {
1176 Wells w;
1177 w.insert({"test_well", Well::serializationTestObject()});
1178
1179 return w;
1180 }
1181 };
1182
1184 {
1185 std::unordered_map<std::string, WellBlockAvgPress> values{};
1186
1187 template <class MessageBufferType>
1188 void write(MessageBufferType& buffer) const;
1189
1190 template <class MessageBufferType>
1191 void read(MessageBufferType& buffer);
1192
1193 bool operator==(const WellBlockAveragePressures& that) const
1194 {
1195 return this->values == that.values;
1196 }
1197
1198 template <class Serializer>
1199 void serializeOp(Serializer& serializer)
1200 {
1201 serializer(this->values);
1202 }
1203
1204 static WellBlockAveragePressures serializationTestObject()
1205 {
1206 return {
1207 { { "I-45", WellBlockAvgPress::serializationTestObject() } },
1208 };
1209 }
1210 };
1211
1212 /* IMPLEMENTATIONS */
1213
1214 inline bool Rates::has( opt m ) const {
1215 const auto mand = static_cast< enum_size >( this->mask )
1216 & static_cast< enum_size >( m );
1217
1218 return static_cast< opt >( mand ) == m;
1219 }
1220
1221 inline double Rates::get( opt m ) const {
1222 if( !this->has( m ) )
1223 throw std::invalid_argument( "Uninitialized value." );
1224
1225 return this->get_ref( m );
1226 }
1227
1228 inline double Rates::get( opt m, double default_value ) const {
1229 if( !this->has( m ) ) return default_value;
1230
1231 return this->get_ref( m );
1232 }
1233
1234 inline double Rates::get( opt m, double default_value, const std::string& tracer_name) const {
1235 if( !this->has( m ) ) return default_value;
1236
1237 if( m == opt::tracer && this->tracer.find(tracer_name) == this->tracer.end()) return default_value;
1238
1239 return this->get_ref( m, tracer_name);
1240 }
1241
1242 inline Rates& Rates::set( opt m, double value ) {
1243 this->get_ref( m ) = value;
1244
1245 /* mask |= m */
1246 this->mask = static_cast< opt >(
1247 static_cast< enum_size >( this->mask ) |
1248 static_cast< enum_size >( m )
1249 );
1250
1251 return *this;
1252 }
1253
1254 inline Rates& Rates::set( opt m, double value , const std::string& tracer_name ) {
1255 this->get_ref( m , tracer_name) = value;
1256
1257 /* mask |= m */
1258 this->mask = static_cast< opt >(
1259 static_cast< enum_size >( this->mask ) |
1260 static_cast< enum_size >( m )
1261 );
1262
1263 return *this;
1264 }
1265
1266 inline bool Rates::operator==(const Rates& rate) const
1267 {
1268 return mask == rate.mask &&
1269 wat == rate.wat &&
1270 oil == rate.oil &&
1271 gas == rate.gas &&
1272 polymer == rate.polymer &&
1273 solvent == rate.solvent &&
1274 energy == rate.energy &&
1275 dissolved_gas == rate.dissolved_gas &&
1276 vaporized_oil == rate.vaporized_oil &&
1277 reservoir_water == rate.reservoir_water &&
1278 reservoir_oil == rate.reservoir_oil &&
1279 reservoir_gas == rate.reservoir_gas &&
1280 productivity_index_water == rate.productivity_index_water &&
1281 productivity_index_gas == rate.productivity_index_gas &&
1282 productivity_index_oil == rate.productivity_index_oil &&
1283 well_potential_water == rate.well_potential_water &&
1284 well_potential_oil == rate.well_potential_oil &&
1285 well_potential_gas == rate.well_potential_gas &&
1286 brine == rate.brine &&
1287 alq == rate.alq &&
1288 tracer == rate.tracer &&
1289 microbial == rate.microbial &&
1290 oxygen == rate.oxygen &&
1291 urea == rate.urea &&
1292 vaporized_water == rate.vaporized_water &&
1293 mass_gas == rate.mass_gas;
1294 }
1295
1296
1297 /*
1298 * To avoid error-prone and repetitve work when extending rates with new
1299 * values, the get+set methods use this helper get_ref to determine what
1300 * member to manipulate. To add a new option, just add another case
1301 * corresponding to the enum entry in Rates to this function.
1302 *
1303 * This is an implementation detail and understanding this has no
1304 * significant impact on correct use of the class.
1305 */
1306 inline const double& Rates::get_ref( opt m ) const {
1307 switch( m ) {
1308 case opt::wat: return this->wat;
1309 case opt::oil: return this->oil;
1310 case opt::gas: return this->gas;
1311 case opt::polymer: return this->polymer;
1312 case opt::solvent: return this->solvent;
1313 case opt::energy: return this->energy;
1314 case opt::dissolved_gas: return this->dissolved_gas;
1315 case opt::vaporized_oil: return this->vaporized_oil;
1316 case opt::reservoir_water: return this->reservoir_water;
1317 case opt::reservoir_oil: return this->reservoir_oil;
1318 case opt::reservoir_gas: return this->reservoir_gas;
1319 case opt::productivity_index_water: return this->productivity_index_water;
1320 case opt::productivity_index_oil: return this->productivity_index_oil;
1321 case opt::productivity_index_gas: return this->productivity_index_gas;
1322 case opt::well_potential_water: return this->well_potential_water;
1323 case opt::well_potential_oil: return this->well_potential_oil;
1324 case opt::well_potential_gas: return this->well_potential_gas;
1325 case opt::brine: return this->brine;
1326 case opt::alq: return this->alq;
1327 case opt::tracer: /* Should _not_ be called with tracer argument */
1328 break;
1329 case opt::microbial: return this->microbial;
1330 case opt::oxygen: return this->oxygen;
1331 case opt::urea: return this->urea;
1332 case opt::vaporized_water: return this->vaporized_water;
1333 case opt::mass_gas: return this->mass_gas;
1334 }
1335
1336 throw std::invalid_argument(
1337 "Unknown value type '"
1338 + std::to_string( static_cast< enum_size >( m ) )
1339 + "'" );
1340
1341 }
1342
1343 inline const double& Rates::get_ref( opt m, const std::string& tracer_name ) const {
1344 if (m != opt::tracer)
1345 throw std::logic_error("Logic error - should be called with tracer argument");
1346
1347 return this->tracer.at(tracer_name);
1348 }
1349
1350 inline double& Rates::get_ref( opt m ) {
1351 return const_cast< double& >(
1352 static_cast< const Rates* >( this )->get_ref( m )
1353 );
1354 }
1355
1356 inline double& Rates::get_ref( opt m, const std::string& tracer_name ) {
1357 if (m == opt::tracer) this->tracer.emplace(tracer_name, 0.0);
1358 return this->tracer.at(tracer_name);
1359 }
1360
1361 void Rates::init_json(Json::JsonObject& json_data) const {
1362
1363 if (this->has(opt::wat))
1364 json_data.add_item("wat", this->get(opt::wat));
1365
1366 if (this->has(opt::oil))
1367 json_data.add_item("oil", this->get(opt::oil));
1368
1369 if (this->has(opt::gas))
1370 json_data.add_item("gas", this->get(opt::gas));
1371
1372 }
1373
1374 bool inline Rates::flowing() const {
1375 return ((this->wat != 0) ||
1376 (this->oil != 0) ||
1377 (this->gas != 0));
1378 }
1379
1380 inline bool Well::flowing() const noexcept {
1381 return this->rates.flowing();
1382 }
1383
1384 template <class MessageBufferType>
1385 void Rates::write(MessageBufferType& buffer) const {
1386 buffer.write(this->mask);
1387 buffer.write(this->wat);
1388 buffer.write(this->oil);
1389 buffer.write(this->gas);
1390 buffer.write(this->polymer);
1391 buffer.write(this->solvent);
1392 buffer.write(this->energy);
1393 buffer.write(this->dissolved_gas);
1394 buffer.write(this->vaporized_oil);
1395 buffer.write(this->reservoir_water);
1396 buffer.write(this->reservoir_oil);
1397 buffer.write(this->reservoir_gas);
1398 buffer.write(this->productivity_index_water);
1399 buffer.write(this->productivity_index_oil);
1400 buffer.write(this->productivity_index_gas);
1401 buffer.write(this->well_potential_water);
1402 buffer.write(this->well_potential_oil);
1403 buffer.write(this->well_potential_gas);
1404 buffer.write(this->brine);
1405 buffer.write(this->alq);
1406
1407 //tracer:
1408 unsigned int size = this->tracer.size();
1409 buffer.write(size);
1410 for (const auto& [name, rate] : this->tracer) {
1411 buffer.write(name);
1412 buffer.write(rate);
1413 }
1414
1415 buffer.write(this->microbial);
1416 buffer.write(this->oxygen);
1417 buffer.write(this->urea);
1418 buffer.write(this->vaporized_water);
1419 buffer.write(this->mass_gas);
1420 }
1421
1422 template <class MessageBufferType>
1423 void ConnectionFiltrate::write(MessageBufferType& buffer) const {
1424 buffer.write(this->rate);
1425 buffer.write(this->total);
1426 buffer.write(this->skin_factor);
1427 buffer.write(this->thickness);
1428 buffer.write(this->perm);
1429 buffer.write(this->poro);
1430 buffer.write(this->radius);
1431 buffer.write(this->area_of_flow);
1432 }
1433
1434 template <class MessageBufferType>
1435 void Connection::write(MessageBufferType& buffer) const {
1436 buffer.write(this->index);
1437 this->rates.write(buffer);
1438 buffer.write(this->pressure);
1439 buffer.write(this->reservoir_rate);
1440 buffer.write(this->cell_pressure);
1441 buffer.write(this->cell_saturation_water);
1442 buffer.write(this->cell_saturation_gas);
1443 buffer.write(this->effective_Kh);
1444 buffer.write(this->trans_factor);
1445 buffer.write(this->d_factor);
1446 buffer.write(this->compact_mult);
1447 this->filtrate.write(buffer);
1448 this->fract.write(buffer);
1449 }
1450
1451 void Connection::init_json(Json::JsonObject& json_data) const {
1452 auto json_rates = json_data.add_object("rates");
1453 this->rates.init_json(json_rates);
1454
1455 json_data.add_item("global_index", static_cast<int>(this->index));
1456 json_data.add_item("pressure", this->pressure);
1457 json_data.add_item("reservoir_rate", this->reservoir_rate);
1458 json_data.add_item("cell_pressure", this->cell_pressure);
1459 json_data.add_item("swat", this->cell_saturation_water);
1460 json_data.add_item("sgas", this->cell_saturation_gas);
1461 json_data.add_item("Kh", this->effective_Kh);
1462 json_data.add_item("trans_factor", this->trans_factor);
1463 json_data.add_item("d_factor", this->d_factor);
1464 json_data.add_item("compact_mult", this->compact_mult);
1465 }
1466
1467 template <class MessageBufferType>
1468 void Segment::write(MessageBufferType& buffer) const
1469 {
1470 buffer.write(this->segNumber);
1471 this->rates.write(buffer);
1472 this->pressures.write(buffer);
1473 this->velocity.write(buffer);
1474 this->holdup.write(buffer);
1475 this->viscosity.write(buffer);
1476 this->density.write(buffer);
1477 }
1478
1479 template <class MessageBufferType>
1480 void CurrentControl::write(MessageBufferType& buffer) const
1481 {
1482 buffer.write(this->isProducer);
1483 if (this->isProducer) {
1484 buffer.write(this->prod);
1485 }
1486 else {
1487 buffer.write(this->inj);
1488 }
1489 }
1490
1491 template <class MessageBufferType>
1492 void WellBlockAvgPress::write(MessageBufferType& buffer) const
1493 {
1494 for (const auto& quantity : this->wbp_) {
1495 buffer.write(quantity);
1496 }
1497 }
1498
1499 template <class MessageBufferType>
1500 void WellFiltrate::write(MessageBufferType& buffer) const
1501 {
1502 buffer.write(this->rate);
1503 buffer.write(this->total);
1504 buffer.write(this->concentration);
1505 }
1506
1507 template <class MessageBufferType>
1508 void Well::write(MessageBufferType& buffer) const
1509 {
1510 this->rates.write(buffer);
1511
1512 buffer.write(this->bhp);
1513 buffer.write(this->thp);
1514 buffer.write(this->temperature);
1515 buffer.write(this->control);
1516 buffer.write(this->efficiency_scaling_factor);
1517
1518 this->filtrate.write(buffer);
1519
1520 {
1521 const auto status = ::Opm::WellStatus2String(this->dynamicStatus);
1522 buffer.write(status);
1523 }
1524
1525 {
1526 const unsigned int size = this->connections.size();
1527 buffer.write(size);
1528
1529 for (const Connection& comp : this->connections) {
1530 comp.write(buffer);
1531 }
1532 }
1533
1534 {
1535 const auto nSeg =
1536 static_cast<unsigned int>(this->segments.size());
1537 buffer.write(nSeg);
1538
1539 for (const auto& seg : this->segments) {
1540 seg.second.write(buffer);
1541 }
1542 }
1543
1544 this->current_control.write(buffer);
1545 this->guide_rates.write(buffer);
1546 this->limits.write(buffer);
1547 }
1548
1549 template <class MessageBufferType>
1550 void WellBlockAveragePressures::write(MessageBufferType& buffer) const
1551 {
1552 buffer.write(this->values.size());
1553
1554 for (const auto& [well, value] : this->values) {
1555 buffer.write(well);
1556 value.write(buffer);
1557 }
1558 }
1559
1560 template <class MessageBufferType>
1561 void Rates::read(MessageBufferType& buffer) {
1562 buffer.read(this->mask);
1563 buffer.read(this->wat);
1564 buffer.read(this->oil);
1565 buffer.read(this->gas);
1566 buffer.read(this->polymer);
1567 buffer.read(this->solvent);
1568 buffer.read(this->energy);
1569 buffer.read(this->dissolved_gas);
1570 buffer.read(this->vaporized_oil);
1571 buffer.read(this->reservoir_water);
1572 buffer.read(this->reservoir_oil);
1573 buffer.read(this->reservoir_gas);
1574 buffer.read(this->productivity_index_water);
1575 buffer.read(this->productivity_index_oil);
1576 buffer.read(this->productivity_index_gas);
1577 buffer.read(this->well_potential_water);
1578 buffer.read(this->well_potential_oil);
1579 buffer.read(this->well_potential_gas);
1580 buffer.read(this->brine);
1581 buffer.read(this->alq);
1582
1583 //tracer:
1584 unsigned int size;
1585 buffer.read(size);
1586 for (size_t i = 0; i < size; ++i) {
1587 std::string tracer_name;
1588 buffer.read(tracer_name);
1589 double tracer_rate;
1590 buffer.read(tracer_rate);
1591 this->tracer.emplace(tracer_name, tracer_rate);
1592 }
1593
1594 buffer.read(this->microbial);
1595 buffer.read(this->oxygen);
1596 buffer.read(this->urea);
1597 buffer.read(this->vaporized_water);
1598 buffer.read(this->mass_gas);
1599 }
1600
1601 template <class MessageBufferType>
1602 void ConnectionFiltrate::read(MessageBufferType& buffer) {
1603 buffer.read(this->rate);
1604 buffer.read(this->total);
1605 buffer.read(this->skin_factor);
1606 buffer.read(this->thickness);
1607 buffer.read(this->perm);
1608 buffer.read(this->poro);
1609 buffer.read(this->radius);
1610 buffer.read(this->area_of_flow);
1611 }
1612
1613 template <class MessageBufferType>
1614 void Connection::read(MessageBufferType& buffer) {
1615 buffer.read(this->index);
1616 this->rates.read(buffer);
1617 buffer.read(this->pressure);
1618 buffer.read(this->reservoir_rate);
1619 buffer.read(this->cell_pressure);
1620 buffer.read(this->cell_saturation_water);
1621 buffer.read(this->cell_saturation_gas);
1622 buffer.read(this->effective_Kh);
1623 buffer.read(this->trans_factor);
1624 buffer.read(this->d_factor);
1625 buffer.read(this->compact_mult);
1626 this->filtrate.read(buffer);
1627 this->fract.read(buffer);
1628 }
1629
1630 template <class MessageBufferType>
1631 void Segment::read(MessageBufferType& buffer)
1632 {
1633 buffer.read(this->segNumber);
1634 this->rates.read(buffer);
1635 this->pressures.read(buffer);
1636 this->velocity.read(buffer);
1637 this->holdup.read(buffer);
1638 this->viscosity.read(buffer);
1639 this->density.read(buffer);
1640 }
1641
1642 template <class MessageBufferType>
1643 void CurrentControl::read(MessageBufferType& buffer)
1644 {
1645 buffer.read(this->isProducer);
1646 if (this->isProducer) {
1647 buffer.read(this->prod);
1648 }
1649 else {
1650 buffer.read(this->inj);
1651 }
1652 }
1653
1654 template <class MessageBufferType>
1655 void WellBlockAvgPress::read(MessageBufferType& buffer)
1656 {
1657 for (auto& quantity : this->wbp_) {
1658 buffer.read(quantity);
1659 }
1660 }
1661
1662 template <class MessageBufferType>
1663 void WellFiltrate::read(MessageBufferType& buffer)
1664 {
1665 buffer.read(this->rate);
1666 buffer.read(this->total);
1667 buffer.read(this->concentration);
1668 }
1669
1670 template <class MessageBufferType>
1671 void Well::read(MessageBufferType& buffer)
1672 {
1673 this->rates.read(buffer);
1674
1675 buffer.read(this->bhp);
1676 buffer.read(this->thp);
1677 buffer.read(this->temperature);
1678 buffer.read(this->control);
1679 buffer.read(this->efficiency_scaling_factor);
1680
1681 this->filtrate.read(buffer);
1682
1683 {
1684 auto status = std::string{};
1685 buffer.read(status);
1686 this->dynamicStatus = ::Opm::WellStatusFromString(status);
1687 }
1688
1689 // Connection information
1690 {
1691 unsigned int size = 0;
1692 buffer.read(size);
1693
1694 this->connections.resize(size);
1695 for (auto& connection : this->connections) {
1696 connection.read(buffer);
1697 }
1698 }
1699
1700 // Segment information (if applicable)
1701 const auto nSeg = [&buffer]() -> unsigned int
1702 {
1703 auto n = 0u;
1704 buffer.read(n);
1705
1706 return n;
1707 }();
1708
1709 for (auto segID = 0*nSeg; segID < nSeg; ++segID) {
1710 auto seg = Segment{};
1711 seg.read(buffer);
1712
1713 const auto segNumber = seg.segNumber;
1714 this->segments.emplace(segNumber, std::move(seg));
1715 }
1716
1717 this->current_control.read(buffer);
1718 this->guide_rates.read(buffer);
1719 this->limits.read(buffer);
1720 }
1721
1722 template <class MessageBufferType>
1723 void WellBlockAveragePressures::read(MessageBufferType& buffer)
1724 {
1725 const auto numWells = [&buffer, this]()
1726 {
1727 auto size = 0*this->values.size();
1728 buffer.read(size);
1729
1730 return size;
1731 }();
1732
1733 auto wellName = std::string{};
1734 for (auto well = 0*numWells; well < numWells; ++well) {
1735 buffer.read(wellName);
1736
1737 this->values[wellName].read(buffer);
1738 }
1739 }
1740
1741 void Well::init_json(Json::JsonObject& json_data) const {
1742 auto json_connections = json_data.add_array("connections");
1743 for (const auto& conn : this->connections) {
1744 auto json_conn = json_connections.add_object();
1745 conn.init_json(json_conn);
1746 }
1747 auto json_rates = json_data.add_object("rates");
1748 this->rates.init_json(json_rates);
1749
1750 json_data.add_item("bhp", this->bhp);
1751 json_data.add_item("thp", this->thp);
1752 json_data.add_item("temperature", this->temperature);
1753 json_data.add_item("status", ::Opm::WellStatus2String(this->dynamicStatus));
1754
1755 auto json_control = json_data.add_object("control");
1756 this->current_control.init_json(json_control);
1757
1758 auto json_guiderate = json_data.add_object("guiderate");
1759 this->guide_rates.init_json(json_guiderate);
1760 }
1761
1762}} // Opm::data
1763
1764#endif //OPM_OUTPUT_WELLS_HPP
Definition JsonObject.hpp:31
Class for (de-)serializing.
Definition Serializer.hpp:94
Definition GuideRateValue.hpp:32
Definition Wells.hpp:560
Definition Wells.hpp:41
bool flowing() const
Returns true if any of the rates oil, gas, water is nonzero.
Definition Wells.hpp:1374
double get(opt m) const
Read the value indicated by m.
Definition Wells.hpp:1221
Rates & set(opt m, double value)
Set the value specified by m.
Definition Wells.hpp:1242
bool has(opt) const
Query if a value is set.
Definition Wells.hpp:1214
Definition Wells.hpp:492
Definition Wells.hpp:856
Definition Wells.hpp:1096
This class implements a small container which holds the transmissibility mulitpliers for all the face...
Definition Exceptions.hpp:30
Definition Wells.hpp:210
Statistics collection for a single quantity.
Definition Wells.hpp:262
void serializeOp(Serializer &serializer)
Convert between byte array and object representation.
Definition Wells.hpp:291
void write(MessageBufferType &buffer) const
MPI communication protocol–serialisation operation.
Definition Wells.hpp:317
double stdev
Unbiased sample standard deviation.
Definition Wells.hpp:275
double avg
Arithmetic average.
Definition Wells.hpp:264
double min
Minimum value.
Definition Wells.hpp:270
void read(MessageBufferType &buffer)
MPI communication protocol–deserialisation operation.
Definition Wells.hpp:327
double max
Maximum value.
Definition Wells.hpp:267
bool operator==(const Statistics &that) const
Equality predicate.
Definition Wells.hpp:306
static Statistics serializationTestObject()
Create a serialization test object.
Definition Wells.hpp:278
Connection Level Fracturing Statistics.
Definition Wells.hpp:259
void read(MessageBufferType &buffer)
MPI communication protocol–deserialisation operation.
Definition Wells.hpp:405
void write(MessageBufferType &buffer) const
MPI communication protocol–serialisation operation.
Definition Wells.hpp:395
static ConnectionFracturing serializationTestObject()
Create a serialisation test object.
Definition Wells.hpp:351
std::size_t numCells
Sample size.
Definition Wells.hpp:339
bool operator==(const ConnectionFracturing &that) const
Equality predicate.
Definition Wells.hpp:384
Statistics width
Statistical measures for connection's fracture fracture width.
Definition Wells.hpp:348
void serializeOp(Serializer &serializer)
Convert between byte array and object representation.
Definition Wells.hpp:369
Statistics rate
Statistical measures for connection's fracture fracture flow rate.
Definition Wells.hpp:345
Statistics press
Statistical measures for connection's fracture pressures.
Definition Wells.hpp:342
Definition Wells.hpp:415
ConnectionFracturing fract
Connection level fracturing statistics.
Definition Wells.hpp:434
Definition Wells.hpp:801
Definition Wells.hpp:708
Definition Wells.hpp:675
Definition Wells.hpp:748
Definition Wells.hpp:1184
Definition Wells.hpp:941
Definition Wells.hpp:907
Definition Wells.hpp:982