My Project
AquiferFetkovich.hpp
1 /*
2 Copyright 2017 TNO - Heat Transfer & Fluid Dynamics, Modelling & Optimization of the Subsurface
3 Copyright 2017 Statoil ASA.
4 
5 This file is part of the Open Porous Media project (OPM).
6 
7 OPM is free software: you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation, either version 3 of the License, or
10 (at your option) any later version.
11 
12 OPM is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
16 
17 You should have received a copy of the GNU General Public License
18 along 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/AquiferInterface.hpp>
25 
26 #include <opm/output/data/Aquifer.hpp>
27 
28 #include <exception>
29 #include <stdexcept>
30 #include <utility>
31 
32 namespace Opm
33 {
34 
35 template <typename TypeTag>
36 class AquiferFetkovich : public AquiferInterface<TypeTag>
37 {
38 
39 public:
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
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 
92 protected:
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  this->aquifer_pressure_ = this->pa0_;
167  }
168 
169  virtual Scalar aquiferDepth() const override
170  {
171  return this->aqufetp_data_.datum_depth;
172  }
173 }; // Class AquiferFetkovich
174 } // namespace Opm
175 #endif
Definition: AquiferFetkovich.hpp:37
Definition: AquiferInterface.hpp:49
This file contains a set of helper functions used by VFPProd / VFPInj.
Definition: BlackoilPhases.hpp:27