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