My Project
BlackoilAquiferModel_impl.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 namespace Opm
22 {
23 
24 template <typename TypeTag>
25 BlackoilAquiferModel<TypeTag>::BlackoilAquiferModel(Simulator& simulator)
26  : simulator_(simulator)
27 {
28  // Grid needs to support Facetag
29  using Grid = std::remove_const_t<std::remove_reference_t<decltype(simulator.vanguard().grid())>>;
30  static_assert(SupportsFaceTag<Grid>::value, "Grid has to support assumptions about face tag.");
31 
32  init();
33 }
34 
35 template <typename TypeTag>
36 void
37 BlackoilAquiferModel<TypeTag>::initialSolutionApplied()
38 {
39  for (auto& aquifer : aquifers)
40  aquifer->initialSolutionApplied();
41 }
42 
43 template <typename TypeTag>
44 void
45 BlackoilAquiferModel<TypeTag>::initFromRestart(const data::Aquifers& aquiferSoln)
46 {
47  for (auto& aquifer : this->aquifers)
48  aquifer->initFromRestart(aquiferSoln);
49 }
50 
51 template <typename TypeTag>
52 void
53 BlackoilAquiferModel<TypeTag>::beginEpisode()
54 {}
55 
56 template <typename TypeTag>
57 void
58 BlackoilAquiferModel<TypeTag>::beginIteration()
59 {}
60 
61 template <typename TypeTag>
62 void
63 BlackoilAquiferModel<TypeTag>::beginTimeStep()
64 {
65  for (auto& aquifer : aquifers)
66  aquifer->beginTimeStep();
67 }
68 
69 template <typename TypeTag>
70 template <class Context>
71 void
72 BlackoilAquiferModel<TypeTag>::addToSource(RateVector& rates,
73  const Context& context,
74  unsigned spaceIdx,
75  unsigned timeIdx) const
76 {
77  for (auto& aquifer : aquifers)
78  aquifer->addToSource(rates, context, spaceIdx, timeIdx);
79 }
80 
81 template <typename TypeTag>
82 void
83 BlackoilAquiferModel<TypeTag>::addToSource(RateVector& rates,
84  unsigned globalSpaceIdx,
85  unsigned timeIdx) const
86 {
87  for (auto& aquifer : aquifers)
88  aquifer->addToSource(rates, globalSpaceIdx, timeIdx);
89 }
90 
91 template <typename TypeTag>
92 void
93 BlackoilAquiferModel<TypeTag>::endIteration()
94 {}
95 
96 template <typename TypeTag>
97 void
98 BlackoilAquiferModel<TypeTag>::endTimeStep()
99 {
100  for (auto& aquifer : aquifers) {
101  aquifer->endTimeStep();
102  using NumAq = AquiferNumerical<TypeTag>;
103  NumAq* num = dynamic_cast<NumAq*>(aquifer.get());
104  if (num)
105  this->simulator_.vanguard().grid().comm().barrier();
106  }
107 }
108 
109 template <typename TypeTag>
110 void
111 BlackoilAquiferModel<TypeTag>::endEpisode()
112 {}
113 
114 template <typename TypeTag>
115 template <class Restarter>
116 void
117 BlackoilAquiferModel<TypeTag>::serialize(Restarter& /* res */)
118 {
119  // TODO (?)
120  throw std::logic_error("BlackoilAquiferModel::serialize() is not yet implemented");
121 }
122 
123 template <typename TypeTag>
124 template <class Restarter>
125 void
126 BlackoilAquiferModel<TypeTag>::deserialize(Restarter& /* res */)
127 {
128  // TODO (?)
129  throw std::logic_error("BlackoilAquiferModel::deserialize() is not yet implemented");
130 }
131 
132 // Initialize the aquifers in the deck
133 template <typename TypeTag>
134 void
135 BlackoilAquiferModel<TypeTag>::init()
136 {
137  const auto& aquifer = this->simulator_.vanguard().eclState().aquifer();
138 
139  if (!aquifer.active()) {
140  return;
141  }
142 
143  const auto& connections = aquifer.connections();
144  for (const auto& aq : aquifer.ct()) {
145  if (!connections.hasAquiferConnections(aq.aquiferID)) {
146  auto msg = fmt::format("No valid connections for Carter-Tracy aquifer {}, aquifer {} will be ignored.",
147  aq.aquiferID, aq.aquiferID);
148  OpmLog::warning(msg);
149  continue;
150  }
151  auto aqf = std::make_unique<AquiferCarterTracy<TypeTag>>(connections.getConnections(aq.aquiferID),
152  this->simulator_, aq);
153  aquifers.push_back(std::move(aqf));
154  }
155 
156  for (const auto& aq : aquifer.fetp()) {
157  if (!connections.hasAquiferConnections(aq.aquiferID)) {
158  auto msg = fmt::format("No valid connections for Fetkovich aquifer {}, aquifer {} will be ignored.",
159  aq.aquiferID, aq.aquiferID);
160  OpmLog::warning(msg);
161  continue;
162  }
163  auto aqf = std::make_unique<AquiferFetkovich<TypeTag>>(connections.getConnections(aq.aquiferID),
164  this->simulator_, aq);
165  aquifers.push_back(std::move(aqf));
166  }
167 
168  if (aquifer.hasNumericalAquifer()) {
169  const auto& num_aquifers = aquifer.numericalAquifers().aquifers();
170  for ([[maybe_unused]]const auto& [id, aqu] : num_aquifers) {
171  auto aqf = std::make_unique<AquiferNumerical<TypeTag>>(aqu, this->simulator_);
172  aquifers.push_back(std::move(aqf));
173  }
174  }
175 }
176 
177 template<typename TypeTag>
178 data::Aquifers BlackoilAquiferModel<TypeTag>::aquiferData() const
179 {
180  data::Aquifers data;
181  for (const auto& aqu : this->aquifers)
182  data.insert_or_assign(aqu->aquiferID(), aqu->aquiferData());
183 
184  return data;
185 }
186 
187 } // namespace Opm
This file contains a set of helper functions used by VFPProd / VFPInj.
Definition: BlackoilPhases.hpp:27