My Project
Loading...
Searching...
No Matches
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
32namespace Opm { namespace data {
33
34 enum class AquiferType
35 {
36 Fetkovich, CarterTracy, ConstantFlux, 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 template<class Serializer>
56 void serializeOp(Serializer& serializer)
57 {
58 serializer(initVolume);
59 serializer(prodIndex);
60 serializer(timeConstant);
61 }
62
63 static FetkovichData serializationTestObject()
64 {
65 return FetkovichData{1.0, 2.0, 3.0};
66 }
67 };
68
70 {
71 double timeConstant{};
72 double influxConstant{};
73 double waterDensity{};
74 double waterViscosity{};
75
76 double dimensionless_time{};
77 double dimensionless_pressure{};
78
79 bool operator==(const CarterTracyData& other) const;
80
81 // MessageBufferType API should be similar to Dune::MessageBufferIF
82 template <class MessageBufferType>
83 void write(MessageBufferType& buffer) const;
84
85 // MessageBufferType API should be similar to Dune::MessageBufferIF
86 template <class MessageBufferType>
87 void read(MessageBufferType& buffer);
88
89 template<class Serializer>
90 void serializeOp(Serializer& serializer)
91 {
92 serializer(timeConstant);
93 serializer(influxConstant);
94 serializer(waterDensity);
95 serializer(waterViscosity);
96 serializer(dimensionless_time);
97 serializer(dimensionless_pressure);
98 }
99
100 static CarterTracyData serializationTestObject()
101 {
102 return CarterTracyData{1.0, 2.0, 3.0, 4.0, 5.0, 6.0};
103 }
104 };
105
107 {
108 std::vector<double> initPressure{};
109
110 bool operator==(const NumericAquiferData& other) const;
111
112 // MessageBufferType API should be similar to Dune::MessageBufferIF
113 template <class MessageBufferType>
114 void write(MessageBufferType& buffer) const;
115
116 // MessageBufferType API should be similar to Dune::MessageBufferIF
117 template <class MessageBufferType>
118 void read(MessageBufferType& buffer);
119
120 template<class Serializer>
121 void serializeOp(Serializer& serializer)
122 {
123 serializer(initPressure);
124 }
125
126 static NumericAquiferData serializationTestObject()
127 {
128 return NumericAquiferData{{1.0, 2.0, 3.0}};
129 }
130 };
131
132 namespace detail {
133 template <AquiferType>
134 struct TypeMap;
135
136 template <> struct TypeMap<AquiferType::CarterTracy>
137 {
139 };
140
141 template <> struct TypeMap<AquiferType::Fetkovich>
142 {
144 };
145
146 template <> struct TypeMap<AquiferType::Numerical>
147 {
149 };
150
151 template <AquiferType t>
152 using TypeMap_t = typename TypeMap<t>::Alternative;
153 } // namespace detail
154
156 {
157 private:
158 template <typename T>
159 bool is() const
160 {
161 return std::holds_alternative<T>(this->options_);
162 }
163
164 template <typename T>
165 const T* get() const
166 {
167 return this->template is<T>()
168 ? &std::get<T>(this->options_)
169 : nullptr;
170 }
171
172 template <typename T>
173 T* get()
174 {
175 return this->template is<T>()
176 ? &std::get<T>(this->options_)
177 : nullptr;
178 }
179
180 public:
181 TypeSpecificData() = default;
182
183 TypeSpecificData(const TypeSpecificData&) = default;
185
186 TypeSpecificData& operator=(const TypeSpecificData&) = default;
187 TypeSpecificData& operator=(TypeSpecificData&&) = default;
188
189 bool operator==(const TypeSpecificData& that) const
190 {
191 return std::visit(Equal{}, this->options_, that.options_);
192 }
193
194 template <AquiferType t>
195 auto* create()
196 {
197 return &this->options_.emplace<detail::TypeMap_t<t>>();
198 }
199
200 template <AquiferType t>
201 bool is() const
202 {
203 return this->template is<detail::TypeMap_t<t>>();
204 }
205
206 template <AquiferType t>
207 auto const* get() const
208 {
209 return this->template get<detail::TypeMap_t<t>>();
210 }
211
212 template <AquiferType t>
213 auto* getMutable()
214 {
215 return this->template get<detail::TypeMap_t<t>>();
216 }
217
218 template <typename MessageBufferType>
219 void write(MessageBufferType& buffer) const
220 {
221 buffer.write(this->options_.index());
222 std::visit(Write<MessageBufferType>{buffer}, this->options_);
223 }
224
225 template <typename MessageBufferType>
226 void read(MessageBufferType& buffer)
227 {
228 auto type = 0 * this->options_.index();
229 buffer.read(type);
230
231 if (type < std::variant_size_v<Types>) {
232 this->create(type);
233
234 std::visit(Read<MessageBufferType>{buffer}, this->options_);
235 }
236 }
237
238 template<class Serializer>
239 void serializeOp(Serializer& serializer)
240 {
241 serializer(options_);
242 }
243
244 private:
245 using Types = std::variant<std::monostate,
249
250 struct Equal
251 {
252 template <typename T1, typename T2>
253 bool operator()(const T1&, const T2&) const
254 {
255 return false;
256 }
257
258 template <typename T>
259 bool operator()(const T& e1, const T& e2) const
260 {
261 return e1 == e2;
262 }
263
264 bool operator()(const std::monostate&,
265 const std::monostate&) const
266 {
267 return true;
268 }
269 };
270
271 template <typename MessageBufferType>
272 class Read
273 {
274 public:
275 explicit Read(MessageBufferType& buffer)
276 : buffer_{ buffer }
277 {}
278
279 template <typename T>
280 void operator()(T& alternative)
281 {
282 return alternative.read(this->buffer_);
283 }
284
285 void operator()(std::monostate&)
286 {}
287
288 private:
289 MessageBufferType& buffer_;
290 };
291
292 template <typename MessageBufferType>
293 class Write
294 {
295 public:
296 explicit Write(MessageBufferType& buffer)
297 : buffer_{ buffer }
298 {}
299
300 template <typename T>
301 void operator()(const T& alternative) const
302 {
303 return alternative.write(this->buffer_);
304 }
305
306 void operator()(const std::monostate&) const
307 {}
308
309 private:
310 MessageBufferType& buffer_;
311 };
312
313 Types options_{};
314
315 void create(const std::size_t option);
316 };
317
319 {
320 int aquiferID = 0; //< One-based ID, range 1..NANAQ
321 double pressure = 0.0; //< Aquifer pressure
322 double fluxRate = 0.0; //< Aquifer influx rate (liquid aquifer)
323 double volume = 0.0; //< Produced liquid volume
324 double initPressure = 0.0; //< Aquifer's initial pressure
325 double datumDepth = 0.0; //< Aquifer's pressure reference depth
326
327 TypeSpecificData typeData{};
328
329 double get(const std::string& key) const;
330
331 bool operator==(const AquiferData& other) const;
332
333 // MessageBufferType API should be similar to Dune::MessageBufferIF
334 template <class MessageBufferType>
335 void write(MessageBufferType& buffer) const;
336
337 // MessageBufferType API should be similar to Dune::MessageBufferIF
338 template <class MessageBufferType>
339 void read(MessageBufferType& buffer);
340
341 template<class Serializer>
342 void serializeOp(Serializer& serializer)
343 {
344 serializer(aquiferID);
345 serializer(pressure);
346 serializer(fluxRate);
347 serializer(volume);
348 serializer(initPressure);
349 serializer(datumDepth);
350 serializer(typeData);
351 }
352
353 static AquiferData serializationTestObjectF()
354 {
355 auto aquifer = AquiferData {1, 123.456, 56.78, 9.0e10, 290.0, 2515.5};
356 auto* aquFet = aquifer.typeData.create<AquiferType::Fetkovich>();
357 aquFet->initVolume = 1.23;
358 aquFet->prodIndex = 45.67;
359 aquFet->timeConstant = 890.123;
360
361 return aquifer;
362 }
363
364 static AquiferData serializationTestObjectC()
365 {
366 auto aquifer = AquiferData {2, 123.456, 56.78, 9.0e10, 290.0, 2515.5};
367 auto* aquCT = aquifer.typeData.create<AquiferType::CarterTracy>();
368
369 aquCT->timeConstant = 987.65;
370 aquCT->influxConstant = 43.21;
371 aquCT->waterDensity = 1014.5;
372 aquCT->waterViscosity = 0.00318;
373 aquCT->dimensionless_time = 42.0;
374 aquCT->dimensionless_pressure = 2.34;
375
376 return aquifer;
377 }
378
379 static AquiferData serializationTestObjectN()
380 {
381 auto aquifer = AquiferData {3, 123.456, 56.78, 9.0e10, 290.0, 2515.5};
382 auto* aquNum = aquifer.typeData.create<AquiferType::Numerical>();
383
384 aquNum->initPressure = {1.234, 2.345, 3.4, 9.876};
385
386 return aquifer;
387 }
388
389 private:
390 using GetSummaryValue = double (AquiferData::*)() const;
391 using SummaryValueDispatchTable = std::unordered_map<std::string, GetSummaryValue>;
392
393 static SummaryValueDispatchTable summaryValueDispatchTable_;
394
395 double aquiferFlowRate() const;
396 double aquiferPressure() const;
397 double aquiferTotalProduction() const;
398 double carterTracyDimensionlessTime() const;
399 double carterTracyDimensionlessPressure() const;
400 };
401
402 // TODO: not sure what extension we will need
403 using Aquifers = std::map<int, AquiferData>;
404
405 template <class MessageBufferType>
406 void FetkovichData::write(MessageBufferType& buffer) const
407 {
408 buffer.write(this->initVolume);
409 buffer.write(this->prodIndex);
410 buffer.write(this->timeConstant);
411 }
412
413 template <class MessageBufferType>
414 void FetkovichData::read(MessageBufferType& buffer)
415 {
416 buffer.read(this->initVolume);
417 buffer.read(this->prodIndex);
418 buffer.read(this->timeConstant);
419 }
420
421 template <class MessageBufferType>
422 void CarterTracyData::write(MessageBufferType& buffer) const
423 {
424 buffer.write(this->timeConstant);
425 buffer.write(this->influxConstant);
426 buffer.write(this->waterDensity);
427 buffer.write(this->waterViscosity);
428 buffer.write(this->dimensionless_time);
429 buffer.write(this->dimensionless_pressure);
430 }
431
432 template <class MessageBufferType>
433 void CarterTracyData::read(MessageBufferType& buffer)
434 {
435 buffer.read(this->timeConstant);
436 buffer.read(this->influxConstant);
437 buffer.read(this->waterDensity);
438 buffer.read(this->waterViscosity);
439 buffer.read(this->dimensionless_time);
440 buffer.read(this->dimensionless_pressure);
441 }
442
443 template <class MessageBufferType>
444 void NumericAquiferData::write(MessageBufferType& buffer) const
445 {
446 buffer.write(this->initPressure.size());
447
448 for (const auto& pressure : this->initPressure) {
449 buffer.write(pressure);
450 }
451 }
452
453 template <class MessageBufferType>
454 void NumericAquiferData::read(MessageBufferType& buffer)
455 {
456 decltype(this->initPressure.size()) size{};
457 buffer.read(size);
458
459 this->initPressure.resize(size, 0.0);
460 for (auto& pressure : this->initPressure) {
461 buffer.read(pressure);
462 }
463 }
464
465 template <class MessageBufferType>
466 void AquiferData::write(MessageBufferType& buffer) const
467 {
468 buffer.write(this->aquiferID);
469 buffer.write(this->pressure);
470 buffer.write(this->fluxRate);
471 buffer.write(this->volume);
472 buffer.write(this->initPressure);
473 buffer.write(this->datumDepth);
474
475 this->typeData.write(buffer);
476 }
477
478 template <class MessageBufferType>
479 void AquiferData::read(MessageBufferType& buffer)
480 {
481 buffer.read(this->aquiferID);
482 buffer.read(this->pressure);
483 buffer.read(this->fluxRate);
484 buffer.read(this->volume);
485 buffer.read(this->initPressure);
486 buffer.read(this->datumDepth);
487
488 this->typeData.read(buffer);
489 }
490}} // Opm::data
491
492#endif // OPM_OUTPUT_AQUIFER_HPP
Class for (de-)serializing.
Definition Serializer.hpp:84
Definition Aquifer.hpp:156
This class implements a small container which holds the transmissibility mulitpliers for all the face...
Definition Exceptions.hpp:30
Definition Aquifer.hpp:319
Definition Aquifer.hpp:70
Definition Aquifer.hpp:40
Definition Aquifer.hpp:107
Definition Aquifer.hpp:134