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