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  };
76 
77  using enum_size = std::underlying_type< opt >::type;
78 
80  inline bool has( opt ) const;
81 
84  inline double get( opt m ) const;
87  inline double get( opt m, double default_value ) const;
88  inline double get( opt m, double default_value , const std::string& tracer_name ) const;
92  inline Rates& set( opt m, double value );
93  inline Rates& set( opt m, double value , const std::string& tracer_name );
94 
96  inline bool flowing() const;
97 
98  template <class MessageBufferType>
99  void write(MessageBufferType& buffer) const;
100  template <class MessageBufferType>
101  void read(MessageBufferType& buffer);
102 
103  bool operator==(const Rates& rat2) const;
104 
105  inline void init_json(Json::JsonObject& json_data) const;
106  private:
107  double& get_ref( opt );
108  double& get_ref( opt, const std::string& tracer_name );
109  const double& get_ref( opt ) const;
110  const double& get_ref( opt, const std::string& tracer_name ) const;
111 
112  opt mask = static_cast< opt >( 0 );
113 
114  double wat = 0.0;
115  double oil = 0.0;
116  double gas = 0.0;
117  double polymer = 0.0;
118  double solvent = 0.0;
119  double energy = 0.0;
120  double dissolved_gas = 0.0;
121  double vaporized_oil = 0.0;
122  double reservoir_water = 0.0;
123  double reservoir_oil = 0.0;
124  double reservoir_gas = 0.0;
125  double productivity_index_water = 0.0;
126  double productivity_index_oil = 0.0;
127  double productivity_index_gas = 0.0;
128  double well_potential_water = 0.0;
129  double well_potential_oil = 0.0;
130  double well_potential_gas = 0.0;
131  double brine = 0.0;
132  double alq = 0.0;
133  std::map<std::string, double> tracer;
134  double micp = 0.0;
135  };
136 
137  struct Connection {
138  using global_index = size_t;
139  static const constexpr int restart_size = 6;
140 
141  global_index index;
142  Rates rates;
143  double pressure;
144  double reservoir_rate;
145  double cell_pressure;
146  double cell_saturation_water;
147  double cell_saturation_gas;
148  double effective_Kh;
149  double trans_factor;
150 
151  bool operator==(const Connection& conn2) const
152  {
153  return index == conn2.index &&
154  rates == conn2.rates &&
155  pressure == conn2.pressure &&
156  reservoir_rate == conn2.reservoir_rate &&
157  cell_pressure == conn2.cell_pressure &&
158  cell_saturation_water == conn2.cell_saturation_water &&
159  cell_saturation_gas == conn2.cell_saturation_gas &&
160  effective_Kh == conn2.effective_Kh;
161  }
162 
163  template <class MessageBufferType>
164  void write(MessageBufferType& buffer) const;
165  template <class MessageBufferType>
166  void read(MessageBufferType& buffer);
167 
168  inline void init_json(Json::JsonObject& json_data) const;
169  };
170 
172  public:
173  enum class Value : std::size_t {
174  Pressure, PDrop, PDropHydrostatic, PDropAccel, PDropFriction,
175  };
176 
177  double& operator[](const Value i)
178  {
179  return this->values_[this->index(i)];
180  }
181 
182  double operator[](const Value i) const
183  {
184  return this->values_[this->index(i)];
185  }
186 
187  bool operator==(const SegmentPressures& segpres2) const
188  {
189  return this->values_ == segpres2.values_;
190  }
191 
192  template <class MessageBufferType>
193  void write(MessageBufferType& buffer) const
194  {
195  for (const auto& value : this->values_) {
196  buffer.write(value);
197  }
198  }
199 
200  template <class MessageBufferType>
201  void read(MessageBufferType& buffer)
202  {
203  for (auto& value : this->values_) {
204  buffer.read(value);
205  }
206  }
207 
208  private:
209  constexpr static std::size_t numvals = 5;
210 
211  std::array<double, numvals> values_ = {0};
212 
213  std::size_t index(const Value ix) const
214  {
215  return static_cast<std::size_t>(ix);
216  }
217  };
218 
219  struct Segment {
220  Rates rates;
221  SegmentPressures pressures;
222  std::size_t segNumber;
223 
224  bool operator==(const Segment& seg2) const
225  {
226  return rates == seg2.rates &&
227  pressures == seg2.pressures &&
228  segNumber == seg2.segNumber;
229  }
230 
231  template <class MessageBufferType>
232  void write(MessageBufferType& buffer) const;
233 
234  template <class MessageBufferType>
235  void read(MessageBufferType& buffer);
236  };
237 
238  struct CurrentControl {
239  bool isProducer{true};
240 
241  ::Opm::Well::ProducerCMode prod {
242  ::Opm::Well::ProducerCMode::CMODE_UNDEFINED
243  };
244 
245  ::Opm::Well::InjectorCMode inj {
246  ::Opm::Well::InjectorCMode::CMODE_UNDEFINED
247  };
248 
249  bool operator==(const CurrentControl& rhs) const
250  {
251  return (this->isProducer == rhs.isProducer)
252  && ((this->isProducer && (this->prod == rhs.prod)) ||
253  (!this->isProducer && (this->inj == rhs.inj)));
254  }
255 
256  void init_json(Json::JsonObject& json_data) const
257  {
258  if (this->inj == ::Opm::Well::InjectorCMode::CMODE_UNDEFINED)
259  json_data.add_item("inj", "CMODE_UNDEFINED");
260  else
261  json_data.add_item("inj", ::Opm::Well::InjectorCMode2String(this->inj));
262 
263  if (this->prod == ::Opm::Well::ProducerCMode::CMODE_UNDEFINED)
264  json_data.add_item("prod", "CMODE_UNDEFINED");
265  else
266  json_data.add_item("prod", ::Opm::Well::ProducerCMode2String(this->prod));
267  }
268 
269  template <class MessageBufferType>
270  void write(MessageBufferType& buffer) const;
271 
272  template <class MessageBufferType>
273  void read(MessageBufferType& buffer);
274  };
275 
276  struct Well {
277  Rates rates{};
278  double bhp{0.0};
279  double thp{0.0};
280  double temperature{0.0};
281  int control{0};
282 
283  ::Opm::Well::Status dynamicStatus { Opm::Well::Status::OPEN };
284 
285  std::vector< Connection > connections{};
286  std::unordered_map<std::size_t, Segment> segments{};
287  CurrentControl current_control{};
288  GuideRateValue guide_rates{};
289 
290  inline bool flowing() const noexcept;
291  template <class MessageBufferType>
292  void write(MessageBufferType& buffer) const;
293  template <class MessageBufferType>
294  void read(MessageBufferType& buffer);
295 
296  inline void init_json(Json::JsonObject& json_data) const;
297 
298  const Connection* find_connection(Connection::global_index connection_grid_index) const {
299  const auto connection = std::find_if( this->connections.begin() ,
300  this->connections.end() ,
301  [=]( const Connection& c ) {
302  return c.index == connection_grid_index; });
303 
304  if( connection == this->connections.end() )
305  return nullptr;
306 
307  return &*connection;
308  }
309 
310  Connection* find_connection(Connection::global_index connection_grid_index) {
311  auto connection = std::find_if( this->connections.begin() ,
312  this->connections.end() ,
313  [=]( const Connection& c ) {
314  return c.index == connection_grid_index; });
315 
316  if( connection == this->connections.end() )
317  return nullptr;
318 
319  return &*connection;
320  }
321 
322  bool operator==(const Well& well2) const
323  {
324  return rates == well2.rates &&
325  bhp == well2.bhp &&
326  thp == well2.thp &&
327  temperature == well2.temperature &&
328  control == well2.control &&
329  connections == well2.connections &&
330  segments == well2.segments &&
331  current_control == well2.current_control &&
332  guide_rates == well2.guide_rates;
333  }
334  };
335 
336 
337  class Wells: public std::map<std::string , Well> {
338  public:
339 
340  double get(const std::string& well_name , Rates::opt m) const {
341  const auto& well = this->find( well_name );
342  if( well == this->end() ) return 0.0;
343 
344  return well->second.rates.get( m, 0.0 );
345  }
346 
347  double get(const std::string& well_name , Rates::opt m, const std::string& tracer_name) const {
348  const auto& well = this->find( well_name );
349  if( well == this->end() ) return 0.0;
350 
351  return well->second.rates.get( m, 0.0, tracer_name);
352  }
353 
354  double get(const std::string& well_name , Connection::global_index connection_grid_index, Rates::opt m) const {
355  const auto& witr = this->find( well_name );
356  if( witr == this->end() ) return 0.0;
357 
358  const auto& well = witr->second;
359  const auto& connection = std::find_if( well.connections.begin() ,
360  well.connections.end() ,
361  [=]( const Connection& c ) {
362  return c.index == connection_grid_index; });
363 
364  if( connection == well.connections.end() )
365  return 0.0;
366 
367  return connection->rates.get( m, 0.0 );
368  }
369 
370  template <class MessageBufferType>
371  void write(MessageBufferType& buffer) const {
372  unsigned int size = this->size();
373  buffer.write(size);
374  for (const auto& witr : *this) {
375  const std::string& name = witr.first;
376  buffer.write(name);
377  const Well& well = witr.second;
378  well.write(buffer);
379  }
380  }
381 
382  template <class MessageBufferType>
383  void read(MessageBufferType& buffer) {
384  unsigned int size;
385  buffer.read(size);
386  for (size_t i = 0; i < size; ++i) {
387  std::string name;
388  buffer.read(name);
389  Well well;
390  well.read(buffer);
391  this->emplace(name, well);
392  }
393  }
394 
395  void init_json(Json::JsonObject& json_data) const {
396  for (const auto& [wname, well] : *this) {
397  auto json_well = json_data.add_object(wname);
398  well.init_json(json_well);
399  }
400  }
401 
402 
403  Json::JsonObject json() const {
404  Json::JsonObject json_data;
405  this->init_json(json_data);
406  return json_data;
407  }
408 
409  };
410 
411 
412  /* IMPLEMENTATIONS */
413 
414  inline bool Rates::has( opt m ) const {
415  const auto mand = static_cast< enum_size >( this->mask )
416  & static_cast< enum_size >( m );
417 
418  return static_cast< opt >( mand ) == m;
419  }
420 
421  inline double Rates::get( opt m ) const {
422  if( !this->has( m ) )
423  throw std::invalid_argument( "Uninitialized value." );
424 
425  return this->get_ref( m );
426  }
427 
428  inline double Rates::get( opt m, double default_value ) const {
429  if( !this->has( m ) ) return default_value;
430 
431  return this->get_ref( m );
432  }
433 
434  inline double Rates::get( opt m, double default_value, const std::string& tracer_name) const {
435  if( !this->has( m ) ) return default_value;
436 
437  if( m == opt::tracer && this->tracer.find(tracer_name) == this->tracer.end()) return default_value;
438 
439  return this->get_ref( m, tracer_name);
440  }
441 
442  inline Rates& Rates::set( opt m, double value ) {
443  this->get_ref( m ) = value;
444 
445  /* mask |= m */
446  this->mask = static_cast< opt >(
447  static_cast< enum_size >( this->mask ) |
448  static_cast< enum_size >( m )
449  );
450 
451  return *this;
452  }
453 
454  inline Rates& Rates::set( opt m, double value , const std::string& tracer_name ) {
455  this->get_ref( m , tracer_name) = value;
456 
457  /* mask |= m */
458  this->mask = static_cast< opt >(
459  static_cast< enum_size >( this->mask ) |
460  static_cast< enum_size >( m )
461  );
462 
463  return *this;
464  }
465 
466  inline bool Rates::operator==(const Rates& rate) const
467  {
468  return mask == rate.mask &&
469  wat == rate.wat &&
470  oil == rate.oil &&
471  gas == rate.gas &&
472  polymer == rate.polymer &&
473  solvent == rate.solvent &&
474  energy == rate.energy &&
475  dissolved_gas == rate.dissolved_gas &&
476  vaporized_oil == rate.vaporized_oil &&
477  reservoir_water == rate.reservoir_water &&
478  reservoir_oil == rate.reservoir_oil &&
479  reservoir_gas == rate.reservoir_gas &&
480  productivity_index_water == rate.productivity_index_water &&
481  productivity_index_gas == rate.productivity_index_gas &&
482  productivity_index_oil == rate.productivity_index_oil &&
483  well_potential_water == rate.well_potential_water &&
484  well_potential_oil == rate.well_potential_oil &&
485  well_potential_gas == rate.well_potential_gas &&
486  brine == rate.brine &&
487  alq == rate.alq &&
488  tracer == rate.tracer &&
489  micp == rate.micp;
490  }
491 
492 
493  /*
494  * To avoid error-prone and repetitve work when extending rates with new
495  * values, the get+set methods use this helper get_ref to determine what
496  * member to manipulate. To add a new option, just add another case
497  * corresponding to the enum entry in Rates to this function.
498  *
499  * This is an implementation detail and understanding this has no
500  * significant impact on correct use of the class.
501  */
502  inline const double& Rates::get_ref( opt m ) const {
503  switch( m ) {
504  case opt::wat: return this->wat;
505  case opt::oil: return this->oil;
506  case opt::gas: return this->gas;
507  case opt::polymer: return this->polymer;
508  case opt::solvent: return this->solvent;
509  case opt::energy: return this->energy;
510  case opt::dissolved_gas: return this->dissolved_gas;
511  case opt::vaporized_oil: return this->vaporized_oil;
512  case opt::reservoir_water: return this->reservoir_water;
513  case opt::reservoir_oil: return this->reservoir_oil;
514  case opt::reservoir_gas: return this->reservoir_gas;
515  case opt::productivity_index_water: return this->productivity_index_water;
516  case opt::productivity_index_oil: return this->productivity_index_oil;
517  case opt::productivity_index_gas: return this->productivity_index_gas;
518  case opt::well_potential_water: return this->well_potential_water;
519  case opt::well_potential_oil: return this->well_potential_oil;
520  case opt::well_potential_gas: return this->well_potential_gas;
521  case opt::brine: return this->brine;
522  case opt::alq: return this->alq;
523  case opt::tracer: /* Should _not_ be called with tracer argument */
524  break;
525  case opt::micp: return this->micp;
526  }
527 
528  throw std::invalid_argument(
529  "Unknown value type '"
530  + std::to_string( static_cast< enum_size >( m ) )
531  + "'" );
532 
533  }
534 
535  inline const double& Rates::get_ref( opt m, const std::string& tracer_name ) const {
536  if (m != opt::tracer)
537  throw std::logic_error("Logic error - should be called with tracer argument");
538 
539  return this->tracer.at(tracer_name);
540  }
541 
542  inline double& Rates::get_ref( opt m ) {
543  return const_cast< double& >(
544  static_cast< const Rates* >( this )->get_ref( m )
545  );
546  }
547 
548  inline double& Rates::get_ref( opt m, const std::string& tracer_name ) {
549  if (m == opt::tracer) this->tracer.emplace(tracer_name, 0.0);
550  return this->tracer.at(tracer_name);
551  }
552 
553  void Rates::init_json(Json::JsonObject& json_data) const {
554 
555  if (this->has(opt::wat))
556  json_data.add_item("wat", this->get(opt::wat));
557 
558  if (this->has(opt::oil))
559  json_data.add_item("oil", this->get(opt::oil));
560 
561  if (this->has(opt::gas))
562  json_data.add_item("gas", this->get(opt::gas));
563 
564  }
565 
566  bool inline Rates::flowing() const {
567  return ((this->wat != 0) ||
568  (this->oil != 0) ||
569  (this->gas != 0));
570  }
571 
572  inline bool Well::flowing() const noexcept {
573  return this->rates.flowing();
574  }
575 
576  template <class MessageBufferType>
577  void Rates::write(MessageBufferType& buffer) const {
578  buffer.write(this->mask);
579  buffer.write(this->wat);
580  buffer.write(this->oil);
581  buffer.write(this->gas);
582  buffer.write(this->polymer);
583  buffer.write(this->solvent);
584  buffer.write(this->energy);
585  buffer.write(this->dissolved_gas);
586  buffer.write(this->vaporized_oil);
587  buffer.write(this->reservoir_water);
588  buffer.write(this->reservoir_oil);
589  buffer.write(this->reservoir_gas);
590  buffer.write(this->productivity_index_water);
591  buffer.write(this->productivity_index_oil);
592  buffer.write(this->productivity_index_gas);
593  buffer.write(this->well_potential_water);
594  buffer.write(this->well_potential_oil);
595  buffer.write(this->well_potential_gas);
596  buffer.write(this->brine);
597  buffer.write(this->alq);
598  //tracer:
599  unsigned int size = this->tracer.size();
600  buffer.write(size);
601  for (const auto& [name, rate] : this->tracer) {
602  buffer.write(name);
603  buffer.write(rate);
604  }
605  buffer.write(this->micp);
606  }
607 
608  template <class MessageBufferType>
609  void Connection::write(MessageBufferType& buffer) const {
610  buffer.write(this->index);
611  this->rates.write(buffer);
612  buffer.write(this->pressure);
613  buffer.write(this->reservoir_rate);
614  buffer.write(this->cell_pressure);
615  buffer.write(this->cell_saturation_water);
616  buffer.write(this->cell_saturation_gas);
617  buffer.write(this->effective_Kh);
618  buffer.write(this->trans_factor);
619  }
620 
621 
622  void Connection::init_json(Json::JsonObject& json_data) const {
623  auto json_rates = json_data.add_object("rates");
624  this->rates.init_json(json_rates);
625 
626  json_data.add_item("global_index", static_cast<int>(this->index));
627  json_data.add_item("pressure", this->pressure);
628  json_data.add_item("reservoir_rate", this->reservoir_rate);
629  json_data.add_item("cell_pressure", this->cell_pressure);
630  json_data.add_item("swat", this->cell_saturation_water);
631  json_data.add_item("sgas", this->cell_saturation_gas);
632  json_data.add_item("Kh", this->effective_Kh);
633  json_data.add_item("trans_factor", this->trans_factor);
634  }
635 
636  template <class MessageBufferType>
637  void Segment::write(MessageBufferType& buffer) const {
638  buffer.write(this->segNumber);
639  this->rates.write(buffer);
640  this->pressures.write(buffer);
641  }
642 
643  template <class MessageBufferType>
644  void CurrentControl::write(MessageBufferType& buffer) const
645  {
646  buffer.write(this->isProducer);
647  if (this->isProducer) {
648  buffer.write(this->prod);
649  }
650  else {
651  buffer.write(this->inj);
652  }
653  }
654 
655  template <class MessageBufferType>
656  void Well::write(MessageBufferType& buffer) const {
657  this->rates.write(buffer);
658  buffer.write(this->bhp);
659  buffer.write(this->thp);
660  buffer.write(this->temperature);
661  buffer.write(this->control);
662 
663  {
664  const auto status = ::Opm::Well::Status2String(this->dynamicStatus);
665  buffer.write(status);
666  }
667 
668  unsigned int size = this->connections.size();
669  buffer.write(size);
670  for (const Connection& comp : this->connections)
671  comp.write(buffer);
672 
673  {
674  const auto nSeg =
675  static_cast<unsigned int>(this->segments.size());
676  buffer.write(nSeg);
677 
678  for (const auto& seg : this->segments) {
679  seg.second.write(buffer);
680  }
681  }
682 
683  this->current_control.write(buffer);
684  this->guide_rates.write(buffer);
685  }
686 
687  template <class MessageBufferType>
688  void Rates::read(MessageBufferType& buffer) {
689  buffer.read(this->mask);
690  buffer.read(this->wat);
691  buffer.read(this->oil);
692  buffer.read(this->gas);
693  buffer.read(this->polymer);
694  buffer.read(this->solvent);
695  buffer.read(this->energy);
696  buffer.read(this->dissolved_gas);
697  buffer.read(this->vaporized_oil);
698  buffer.read(this->reservoir_water);
699  buffer.read(this->reservoir_oil);
700  buffer.read(this->reservoir_gas);
701  buffer.read(this->productivity_index_water);
702  buffer.read(this->productivity_index_oil);
703  buffer.read(this->productivity_index_gas);
704  buffer.read(this->well_potential_water);
705  buffer.read(this->well_potential_oil);
706  buffer.read(this->well_potential_gas);
707  buffer.read(this->brine);
708  buffer.read(this->alq);
709  //tracer:
710  unsigned int size;
711  buffer.read(size);
712  for (size_t i = 0; i < size; ++i) {
713  std::string tracer_name;
714  buffer.read(tracer_name);
715  double tracer_rate;
716  buffer.read(tracer_rate);
717  this->tracer.emplace(tracer_name, tracer_rate);
718  }
719  buffer.read(this->micp);
720  }
721 
722  template <class MessageBufferType>
723  void Connection::read(MessageBufferType& buffer) {
724  buffer.read(this->index);
725  this->rates.read(buffer);
726  buffer.read(this->pressure);
727  buffer.read(this->reservoir_rate);
728  buffer.read(this->cell_pressure);
729  buffer.read(this->cell_saturation_water);
730  buffer.read(this->cell_saturation_gas);
731  buffer.read(this->effective_Kh);
732  buffer.read(this->trans_factor);
733  }
734 
735  template <class MessageBufferType>
736  void Segment::read(MessageBufferType& buffer) {
737  buffer.read(this->segNumber);
738  this->rates.read(buffer);
739  this->pressures.read(buffer);
740  }
741 
742  template <class MessageBufferType>
743  void CurrentControl::read(MessageBufferType& buffer)
744  {
745  buffer.read(this->isProducer);
746  if (this->isProducer) {
747  buffer.read(this->prod);
748  }
749  else {
750  buffer.read(this->inj);
751  }
752  }
753 
754  template <class MessageBufferType>
755  void Well::read(MessageBufferType& buffer) {
756  this->rates.read(buffer);
757  buffer.read(this->bhp);
758  buffer.read(this->thp);
759  buffer.read(this->temperature);
760  buffer.read(this->control);
761 
762  {
763  auto status = std::string{};
764  buffer.read(status);
765  this->dynamicStatus = ::Opm::Well::StatusFromString(status);
766  }
767 
768  // Connection information
769  unsigned int size = 0.0; //this->connections.size();
770  buffer.read(size);
771  this->connections.resize(size);
772  for (size_t i = 0; i < size; ++i)
773  {
774  auto& comp = this->connections[ i ];
775  comp.read(buffer);
776  }
777 
778  // Segment information (if applicable)
779  const auto nSeg = [&buffer]() -> unsigned int
780  {
781  auto n = 0u;
782  buffer.read(n);
783 
784  return n;
785  }();
786 
787  for (auto segID = 0*nSeg; segID < nSeg; ++segID) {
788  auto seg = Segment{};
789  seg.read(buffer);
790 
791  const auto segNumber = seg.segNumber;
792  this->segments.emplace(segNumber, std::move(seg));
793  }
794 
795  this->current_control.read(buffer);
796  this->guide_rates.read(buffer);
797  }
798 
799  void Well::init_json(Json::JsonObject& json_data) const {
800  auto json_connections = json_data.add_array("connections");
801  for (const auto& conn : this->connections) {
802  auto json_conn = json_connections.add_object();
803  conn.init_json(json_conn);
804  }
805  auto json_rates = json_data.add_object("rates");
806  this->rates.init_json(json_rates);
807 
808  json_data.add_item("bhp", this->bhp);
809  json_data.add_item("thp", this->thp);
810  json_data.add_item("temperature", this->temperature);
811  json_data.add_item("status", ::Opm::Well::Status2String(this->dynamicStatus));
812 
813  auto json_control = json_data.add_object("control");
814  this->current_control.init_json(json_control);
815 
816  auto json_guiderate = json_data.add_object("guiderate");
817  this->guide_rates.init_json(json_guiderate);
818  }
819 
820 }} // Opm::data
821 
822 #endif //OPM_OUTPUT_WELLS_HPP
Definition: JsonObject.hpp:32
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:566
double get(opt m) const
Read the value indicated by m.
Definition: Wells.hpp:421
Rates & set(opt m, double value)
Set the value specified by m.
Definition: Wells.hpp:442
bool has(opt) const
Query if a value is set.
Definition: Wells.hpp:414
Definition: Wells.hpp:171
Definition: Wells.hpp:337
This class implements a small container which holds the transmissibility mulitpliers for all the face...
Definition: Exceptions.hpp:29
Definition: Wells.hpp:137
Definition: Wells.hpp:238
Definition: Wells.hpp:219
Definition: Wells.hpp:276