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