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