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