My Project
AquiferFetkovich.hpp
1/*
2Copyright 2017 TNO - Heat Transfer & Fluid Dynamics, Modelling & Optimization of the Subsurface
3Copyright 2017 Statoil ASA.
4
5This file is part of the Open Porous Media project (OPM).
6
7OPM is free software: you can redistribute it and/or modify
8it under the terms of the GNU General Public License as published by
9the Free Software Foundation, either version 3 of the License, or
10(at your option) any later version.
11
12OPM is distributed in the hope that it will be useful,
13but WITHOUT ANY WARRANTY; without even the implied warranty of
14MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15GNU General Public License for more details.
16
17You should have received a copy of the GNU General Public License
18along with OPM. If not, see <http://www.gnu.org/licenses/>.
19*/
20
21#ifndef OPM_AQUIFETP_HEADER_INCLUDED
22#define OPM_AQUIFETP_HEADER_INCLUDED
23
24#include <opm/simulators/aquifers/AquiferAnalytical.hpp>
25
26#include <opm/input/eclipse/EclipseState/Aquifer/Aquifetp.hpp>
27
28#include <opm/output/data/Aquifer.hpp>
29
30#include <exception>
31#include <stdexcept>
32#include <utility>
33
34namespace Opm
35{
36
37template <typename TypeTag>
38class AquiferFetkovich : public AquiferAnalytical<TypeTag>
39{
40
41public:
43
44 using typename Base::BlackoilIndices;
45 using typename Base::ElementContext;
46 using typename Base::Eval;
47 using typename Base::FluidState;
48 using typename Base::FluidSystem;
49 using typename Base::IntensiveQuantities;
50 using typename Base::RateVector;
51 using typename Base::Scalar;
52 using typename Base::Simulator;
53 using typename Base::ElementMapper;
54
55 AquiferFetkovich(const std::vector<Aquancon::AquancCell>& connections,
56 const Simulator& ebosSimulator,
57 const Aquifetp::AQUFETP_data& aqufetp_data)
58 : Base(aqufetp_data.aquiferID, connections, ebosSimulator)
59 , aqufetp_data_(aqufetp_data)
60 {
61 }
62
63 static AquiferFetkovich serializationTestObject(const Simulator& ebosSimulator)
64 {
65 AquiferFetkovich result({}, ebosSimulator, {});
66
67 result.pressure_previous_ = {1.0, 2.0, 3.0};
68 result.pressure_current_ = {4.0, 5.0};
69 result.Qai_ = {{6.0}};
70 result.rhow_ = 7.0;
71 result.W_flux_ = 8.0;
72 result.aquifer_pressure_ = 9.0;
73
74 return result;
75 }
76
77 void endTimeStep() override
78 {
79 for (const auto& q : this->Qai_) {
80 this->W_flux_ += q * this->ebos_simulator_.timeStepSize();
81 }
82 aquifer_pressure_ = aquiferPressure();
83 }
84
85 data::AquiferData aquiferData() const override
86 {
87 // TODO: how to unify the two functions?
88 auto data = data::AquiferData{};
89
90 data.aquiferID = this->aquiferID();
91 data.pressure = this->aquifer_pressure_;
92 data.fluxRate = std::accumulate(this->Qai_.begin(), this->Qai_.end(), 0.0,
93 [](const double flux, const auto& q) -> double
94 {
95 return flux + q.value();
96 });
97 data.volume = this->W_flux_.value();
98 data.initPressure = this->pa0_;
99
100 auto* aquFet = data.typeData.template create<data::AquiferType::Fetkovich>();
101 aquFet->initVolume = this->aqufetp_data_.initial_watvolume;
102 aquFet->prodIndex = this->aqufetp_data_.prod_index;
103 aquFet->timeConstant = this->aqufetp_data_.timeConstant();
104
105 return data;
106 }
107
108 template<class Serializer>
109 void serializeOp(Serializer& serializer)
110 {
111 serializer(static_cast<Base&>(*this));
112 serializer(aquifer_pressure_);
113 }
114
115 bool operator==(const AquiferFetkovich& rhs) const
116 {
117 return static_cast<const Base&>(*this) == rhs &&
118 this->aquifer_pressure_ == rhs.aquifer_pressure_;
119 }
120
121protected:
122 // Aquifer Fetkovich Specific Variables
123 Aquifetp::AQUFETP_data aqufetp_data_;
124 Scalar aquifer_pressure_; // aquifer
125
126 void assignRestartData(const data::AquiferData& xaq) override
127 {
128 if (! xaq.typeData.is<data::AquiferType::Fetkovich>()) {
129 throw std::invalid_argument {
130 "Analytic aquifer data for unexpected aquifer "
131 "type passed to Fetkovich aquifer"
132 };
133 }
134
135 this->aquifer_pressure_ = xaq.pressure;
136 this->rhow_ = this->aqufetp_data_.waterDensity();
137 }
138
139 inline Eval dpai(int idx)
140 {
141 const auto gdz =
142 this->gravity_() * (this->cell_depth_[idx] - this->aquiferDepth());
143
144 return this->aquifer_pressure_ + this->rhow_*gdz
145 - this->pressure_current_.at(idx);
146 }
147
148 // This function implements Eq 5.12 of the EclipseTechnicalDescription
149 inline Scalar aquiferPressure()
150 {
151 Scalar Flux = this->W_flux_.value();
152
153 const auto& comm = this->ebos_simulator_.vanguard().grid().comm();
154 comm.sum(&Flux, 1);
155
156 const auto denom =
157 this->aqufetp_data_.total_compr * this->aqufetp_data_.initial_watvolume;
158
159 return this->pa0_ - (Flux / denom);
160 }
161
162 inline void calculateAquiferConstants() override
163 {
164 this->Tc_ = this->aqufetp_data_.timeConstant();
165 }
166
167 // This function implements Eq 5.14 of the EclipseTechnicalDescription
168 inline void calculateInflowRate(int idx, const Simulator& simulator) override
169 {
170 const Scalar td_Tc_ = simulator.timeStepSize() / this->Tc_;
171 const Scalar coef = (1 - exp(-td_Tc_)) / td_Tc_;
172
173 this->Qai_.at(idx) = coef * this->alphai_[idx] *
174 this->aqufetp_data_.prod_index * dpai(idx);
175 }
176
177 inline void calculateAquiferCondition() override
178 {
179 if (this->solution_set_from_restart_) {
180 return;
181 }
182
183 if (! this->aqufetp_data_.initial_pressure.has_value()) {
184 this->aqufetp_data_.initial_pressure =
185 this->calculateReservoirEquilibrium();
186
187 const auto& tables = this->ebos_simulator_.vanguard()
188 .eclState().getTableManager();
189
190 this->aqufetp_data_.finishInitialisation(tables);
191 }
192
193 this->rhow_ = this->aqufetp_data_.waterDensity();
194 this->pa0_ = this->aqufetp_data_.initial_pressure.value();
195 if (this->aqufetp_data_.initial_temperature.has_value())
196 this->Ta0_ = this->aqufetp_data_.initial_temperature.value();
197 this->aquifer_pressure_ = this->pa0_;
198 }
199
200 virtual Scalar aquiferDepth() const override
201 {
202 return this->aqufetp_data_.datum_depth;
203 }
204}; // Class AquiferFetkovich
205
206} // namespace Opm
207
208#endif
Definition: AquiferAnalytical.hpp:55
Definition: AquiferFetkovich.hpp:39
This file contains a set of helper functions used by VFPProd / VFPInj.
Definition: BlackoilPhases.hpp:27