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/output/data/Aquifer.hpp>
27
28#include <exception>
29#include <stdexcept>
30#include <utility>
31
32namespace Opm
33{
34
35template <typename TypeTag>
36class AquiferFetkovich : public AquiferAnalytical<TypeTag>
37{
38
39public:
41
42 using typename Base::BlackoilIndices;
43 using typename Base::ElementContext;
44 using typename Base::Eval;
45 using typename Base::FluidState;
46 using typename Base::FluidSystem;
47 using typename Base::IntensiveQuantities;
48 using typename Base::RateVector;
49 using typename Base::Scalar;
50 using typename Base::Simulator;
51 using typename Base::ElementMapper;
52
53 AquiferFetkovich(const std::vector<Aquancon::AquancCell>& connections,
54 const Simulator& ebosSimulator,
55 const Aquifetp::AQUFETP_data& aqufetp_data)
56 : Base(aqufetp_data.aquiferID, connections, ebosSimulator)
57 , aqufetp_data_(aqufetp_data)
58 {
59 }
60
61 void endTimeStep() override
62 {
63 for (const auto& q : this->Qai_) {
64 this->W_flux_ += q * this->ebos_simulator_.timeStepSize();
65 }
66 aquifer_pressure_ = aquiferPressure();
67 }
68
69 data::AquiferData aquiferData() const override
70 {
71 // TODO: how to unify the two functions?
72 auto data = data::AquiferData{};
73
74 data.aquiferID = this->aquiferID();
75 data.pressure = this->aquifer_pressure_;
76 data.fluxRate = std::accumulate(this->Qai_.begin(), this->Qai_.end(), 0.0,
77 [](const double flux, const auto& q) -> double
78 {
79 return flux + q.value();
80 });
81 data.volume = this->W_flux_.value();
82 data.initPressure = this->pa0_;
83
84 auto* aquFet = data.typeData.template create<data::AquiferType::Fetkovich>();
85 aquFet->initVolume = this->aqufetp_data_.initial_watvolume;
86 aquFet->prodIndex = this->aqufetp_data_.prod_index;
87 aquFet->timeConstant = this->aqufetp_data_.timeConstant();
88
89 return data;
90 }
91
92protected:
93 // Aquifer Fetkovich Specific Variables
94 Aquifetp::AQUFETP_data aqufetp_data_;
95 Scalar aquifer_pressure_; // aquifer
96
97 void assignRestartData(const data::AquiferData& xaq) override
98 {
99 if (! xaq.typeData.is<data::AquiferType::Fetkovich>()) {
100 throw std::invalid_argument {
101 "Analytic aquifer data for unexpected aquifer "
102 "type passed to Fetkovich aquifer"
103 };
104 }
105
106 this->aquifer_pressure_ = xaq.pressure;
107 this->rhow_ = this->aqufetp_data_.waterDensity();
108 }
109
110 inline Eval dpai(int idx)
111 {
112 const auto gdz =
113 this->gravity_() * (this->cell_depth_[idx] - this->aquiferDepth());
114
115 return this->aquifer_pressure_ + this->rhow_*gdz
116 - this->pressure_current_.at(idx);
117 }
118
119 // This function implements Eq 5.12 of the EclipseTechnicalDescription
120 inline Scalar aquiferPressure()
121 {
122 Scalar Flux = this->W_flux_.value();
123
124 const auto& comm = this->ebos_simulator_.vanguard().grid().comm();
125 comm.sum(&Flux, 1);
126
127 const auto denom =
128 this->aqufetp_data_.total_compr * this->aqufetp_data_.initial_watvolume;
129
130 return this->pa0_ - (Flux / denom);
131 }
132
133 inline void calculateAquiferConstants() override
134 {
135 this->Tc_ = this->aqufetp_data_.timeConstant();
136 }
137
138 // This function implements Eq 5.14 of the EclipseTechnicalDescription
139 inline void calculateInflowRate(int idx, const Simulator& simulator) override
140 {
141 const Scalar td_Tc_ = simulator.timeStepSize() / this->Tc_;
142 const Scalar coef = (1 - exp(-td_Tc_)) / td_Tc_;
143
144 this->Qai_.at(idx) = coef * this->alphai_[idx] *
145 this->aqufetp_data_.prod_index * dpai(idx);
146 }
147
148 inline void calculateAquiferCondition() override
149 {
150 if (this->solution_set_from_restart_) {
151 return;
152 }
153
154 if (! this->aqufetp_data_.initial_pressure.has_value()) {
155 this->aqufetp_data_.initial_pressure =
156 this->calculateReservoirEquilibrium();
157
158 const auto& tables = this->ebos_simulator_.vanguard()
159 .eclState().getTableManager();
160
161 this->aqufetp_data_.finishInitialisation(tables);
162 }
163
164 this->rhow_ = this->aqufetp_data_.waterDensity();
165 this->pa0_ = this->aqufetp_data_.initial_pressure.value();
166 if (this->aqufetp_data_.initial_temperature.has_value())
167 this->Ta0_ = this->aqufetp_data_.initial_temperature.value();
168 this->aquifer_pressure_ = this->pa0_;
169 }
170
171 virtual Scalar aquiferDepth() const override
172 {
173 return this->aqufetp_data_.datum_depth;
174 }
175}; // Class AquiferFetkovich
176
177} // namespace Opm
178
179#endif
Definition: AquiferAnalytical.hpp:51
Definition: AquiferFetkovich.hpp:37
This file contains a set of helper functions used by VFPProd / VFPInj.
Definition: BlackoilPhases.hpp:27