My Project
Aquifer.hpp
1 /*
2  Copyright 2019 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_AQUIFER_HPP
21 #define OPM_OUTPUT_AQUIFER_HPP
22 
23 #include <cstddef>
24 #include <map>
25 #include <memory>
26 #include <string>
27 #include <unordered_map>
28 #include <utility>
29 #include <variant>
30 #include <vector>
31 
32 namespace Opm { namespace data {
33 
34  enum class AquiferType
35  {
36  Fetkovich, CarterTracy, Numerical,
37  };
38 
40  {
41  double initVolume{};
42  double prodIndex{};
43  double timeConstant{};
44 
45  bool operator==(const FetkovichData& other) const;
46 
47  // MessageBufferType API should be similar to Dune::MessageBufferIF
48  template <class MessageBufferType>
49  void write(MessageBufferType& buffer) const;
50 
51  // MessageBufferType API should be similar to Dune::MessageBufferIF
52  template <class MessageBufferType>
53  void read(MessageBufferType& buffer);
54  };
55 
57  {
58  double timeConstant{};
59  double influxConstant{};
60  double waterDensity{};
61  double waterViscosity{};
62 
63  double dimensionless_time{};
64  double dimensionless_pressure{};
65 
66  bool operator==(const CarterTracyData& other) const;
67 
68  // MessageBufferType API should be similar to Dune::MessageBufferIF
69  template <class MessageBufferType>
70  void write(MessageBufferType& buffer) const;
71 
72  // MessageBufferType API should be similar to Dune::MessageBufferIF
73  template <class MessageBufferType>
74  void read(MessageBufferType& buffer);
75  };
76 
78  {
79  std::vector<double> initPressure{};
80 
81  bool operator==(const NumericAquiferData& other) const;
82 
83  // MessageBufferType API should be similar to Dune::MessageBufferIF
84  template <class MessageBufferType>
85  void write(MessageBufferType& buffer) const;
86 
87  // MessageBufferType API should be similar to Dune::MessageBufferIF
88  template <class MessageBufferType>
89  void read(MessageBufferType& buffer);
90  };
91 
92  namespace detail {
93  template <AquiferType>
94  struct TypeMap;
95 
96  template <> struct TypeMap<AquiferType::CarterTracy>
97  {
99  };
100 
101  template <> struct TypeMap<AquiferType::Fetkovich>
102  {
103  using Alternative = FetkovichData;
104  };
105 
106  template <> struct TypeMap<AquiferType::Numerical>
107  {
109  };
110 
111  template <AquiferType t>
112  using TypeMap_t = typename TypeMap<t>::Alternative;
113  } // namespace detail
114 
116  {
117  private:
118  template <typename T>
119  bool is() const
120  {
121  return std::holds_alternative<T>(this->options_);
122  }
123 
124  template <typename T>
125  const T* get() const
126  {
127  return this->template is<T>()
128  ? &std::get<T>(this->options_)
129  : nullptr;
130  }
131 
132  template <typename T>
133  T* get()
134  {
135  return this->template is<T>()
136  ? &std::get<T>(this->options_)
137  : nullptr;
138  }
139 
140  public:
141  TypeSpecificData() = default;
142 
143  TypeSpecificData(const TypeSpecificData&) = default;
144  TypeSpecificData(TypeSpecificData&&) = default;
145 
146  TypeSpecificData& operator=(const TypeSpecificData&) = default;
147  TypeSpecificData& operator=(TypeSpecificData&&) = default;
148 
149  bool operator==(const TypeSpecificData& that) const
150  {
151  return std::visit(Equal{}, this->options_, that.options_);
152  }
153 
154  template <AquiferType t>
155  auto* create()
156  {
157  return &this->options_.emplace<detail::TypeMap_t<t>>();
158  }
159 
160  template <AquiferType t>
161  bool is() const
162  {
163  return this->template is<detail::TypeMap_t<t>>();
164  }
165 
166  template <AquiferType t>
167  auto const* get() const
168  {
169  return this->template get<detail::TypeMap_t<t>>();
170  }
171 
172  template <AquiferType t>
173  auto* getMutable()
174  {
175  return this->template get<detail::TypeMap_t<t>>();
176  }
177 
178  template <typename MessageBufferType>
179  void write(MessageBufferType& buffer) const
180  {
181  buffer.write(this->options_.index());
182  std::visit(Write<MessageBufferType>{buffer}, this->options_);
183  }
184 
185  template <typename MessageBufferType>
186  void read(MessageBufferType& buffer)
187  {
188  auto type = 0 * this->options_.index();
189  buffer.read(type);
190 
191  if (type < std::variant_size_v<Types>) {
192  this->create(type);
193 
194  std::visit(Read<MessageBufferType>{buffer}, this->options_);
195  }
196  }
197 
198  private:
199  using Types = std::variant<std::monostate,
203 
204  struct Equal
205  {
206  template <typename T1, typename T2>
207  bool operator()(const T1&, const T2&) const
208  {
209  return false;
210  }
211 
212  template <typename T>
213  bool operator()(const T& e1, const T& e2) const
214  {
215  return e1 == e2;
216  }
217 
218  bool operator()(const std::monostate&,
219  const std::monostate&) const
220  {
221  return true;
222  }
223  };
224 
225  template <typename MessageBufferType>
226  class Read
227  {
228  public:
229  explicit Read(MessageBufferType& buffer)
230  : buffer_{ buffer }
231  {}
232 
233  template <typename T>
234  void operator()(T& alternative)
235  {
236  return alternative.read(this->buffer_);
237  }
238 
239  void operator()(std::monostate&)
240  {}
241 
242  private:
243  MessageBufferType& buffer_;
244  };
245 
246  template <typename MessageBufferType>
247  class Write
248  {
249  public:
250  explicit Write(MessageBufferType& buffer)
251  : buffer_{ buffer }
252  {}
253 
254  template <typename T>
255  void operator()(const T& alternative) const
256  {
257  return alternative.write(this->buffer_);
258  }
259 
260  void operator()(const std::monostate&) const
261  {}
262 
263  private:
264  MessageBufferType& buffer_;
265  };
266 
267  Types options_{};
268 
269  void create(const std::size_t option);
270  };
271 
272  struct AquiferData
273  {
274  int aquiferID = 0; //< One-based ID, range 1..NANAQ
275  double pressure = 0.0; //< Aquifer pressure
276  double fluxRate = 0.0; //< Aquifer influx rate (liquid aquifer)
277  double volume = 0.0; //< Produced liquid volume
278  double initPressure = 0.0; //< Aquifer's initial pressure
279  double datumDepth = 0.0; //< Aquifer's pressure reference depth
280 
281  TypeSpecificData typeData{};
282 
283  double get(const std::string& key) const;
284 
285  bool operator==(const AquiferData& other) const;
286 
287  // MessageBufferType API should be similar to Dune::MessageBufferIF
288  template <class MessageBufferType>
289  void write(MessageBufferType& buffer) const;
290 
291  // MessageBufferType API should be similar to Dune::MessageBufferIF
292  template <class MessageBufferType>
293  void read(MessageBufferType& buffer);
294 
295  private:
296  using GetSummaryValue = double (AquiferData::*)() const;
297  using SummaryValueDispatchTable = std::unordered_map<std::string, GetSummaryValue>;
298 
299  static SummaryValueDispatchTable summaryValueDispatchTable_;
300 
301  double aquiferFlowRate() const;
302  double aquiferPressure() const;
303  double aquiferTotalProduction() const;
304  double carterTracyDimensionlessTime() const;
305  double carterTracyDimensionlessPressure() const;
306  };
307 
308  // TODO: not sure what extension we will need
309  using Aquifers = std::map<int, AquiferData>;
310 
311  template <class MessageBufferType>
312  void FetkovichData::write(MessageBufferType& buffer) const
313  {
314  buffer.write(this->initVolume);
315  buffer.write(this->prodIndex);
316  buffer.write(this->timeConstant);
317  }
318 
319  template <class MessageBufferType>
320  void FetkovichData::read(MessageBufferType& buffer)
321  {
322  buffer.read(this->initVolume);
323  buffer.read(this->prodIndex);
324  buffer.read(this->timeConstant);
325  }
326 
327  template <class MessageBufferType>
328  void CarterTracyData::write(MessageBufferType& buffer) const
329  {
330  buffer.write(this->timeConstant);
331  buffer.write(this->influxConstant);
332  buffer.write(this->waterDensity);
333  buffer.write(this->waterViscosity);
334  buffer.write(this->dimensionless_time);
335  buffer.write(this->dimensionless_pressure);
336  }
337 
338  template <class MessageBufferType>
339  void CarterTracyData::read(MessageBufferType& buffer)
340  {
341  buffer.read(this->timeConstant);
342  buffer.read(this->influxConstant);
343  buffer.read(this->waterDensity);
344  buffer.read(this->waterViscosity);
345  buffer.read(this->dimensionless_time);
346  buffer.read(this->dimensionless_pressure);
347  }
348 
349  template <class MessageBufferType>
350  void NumericAquiferData::write(MessageBufferType& buffer) const
351  {
352  buffer.write(this->initPressure.size());
353 
354  for (const auto& pressure : this->initPressure) {
355  buffer.write(pressure);
356  }
357  }
358 
359  template <class MessageBufferType>
360  void NumericAquiferData::read(MessageBufferType& buffer)
361  {
362  decltype(this->initPressure.size()) size{};
363  buffer.read(size);
364 
365  this->initPressure.resize(size, 0.0);
366  for (auto& pressure : this->initPressure) {
367  buffer.read(pressure);
368  }
369  }
370 
371  template <class MessageBufferType>
372  void AquiferData::write(MessageBufferType& buffer) const
373  {
374  buffer.write(this->aquiferID);
375  buffer.write(this->pressure);
376  buffer.write(this->fluxRate);
377  buffer.write(this->volume);
378  buffer.write(this->initPressure);
379  buffer.write(this->datumDepth);
380 
381  this->typeData.write(buffer);
382  }
383 
384  template <class MessageBufferType>
385  void AquiferData::read(MessageBufferType& buffer)
386  {
387  buffer.read(this->aquiferID);
388  buffer.read(this->pressure);
389  buffer.read(this->fluxRate);
390  buffer.read(this->volume);
391  buffer.read(this->initPressure);
392  buffer.read(this->datumDepth);
393 
394  this->typeData.read(buffer);
395  }
396 }} // Opm::data
397 
398 #endif // OPM_OUTPUT_AQUIFER_HPP
Definition: Aquifer.hpp:116
This class implements a small container which holds the transmissibility mulitpliers for all the face...
Definition: Exceptions.hpp:29
Definition: Aquifer.hpp:273
Definition: Aquifer.hpp:57
Definition: Aquifer.hpp:40
Definition: Aquifer.hpp:78
Definition: Aquifer.hpp:94