21#include <opm/simulators/aquifers/AquiferConstantFlux.hpp>
23#include <opm/common/ErrorMacros.hpp>
33template <
typename TypeTag>
34BlackoilAquiferModel<TypeTag>::BlackoilAquiferModel(Simulator& simulator)
35 : simulator_(simulator)
38 using Grid = std::remove_const_t<std::remove_reference_t<
decltype(simulator.vanguard().grid())>>;
39 static_assert(SupportsFaceTag<Grid>::value,
"Grid has to support assumptions about face tag.");
44template <
typename TypeTag>
46BlackoilAquiferModel<TypeTag>::initialSolutionApplied()
48 for (
auto& aquifer : aquifers)
49 aquifer->initialSolutionApplied();
52template <
typename TypeTag>
54BlackoilAquiferModel<TypeTag>::initFromRestart(
const data::Aquifers& aquiferSoln)
56 for (
auto& aquifer : this->aquifers)
57 aquifer->initFromRestart(aquiferSoln);
60template <
typename TypeTag>
62BlackoilAquiferModel<TypeTag>::beginEpisode()
69 this->createDynamicAquifers(this->simulator_.episodeIndex());
72template <
typename TypeTag>
74BlackoilAquiferModel<TypeTag>::beginIteration()
77template <
typename TypeTag>
79BlackoilAquiferModel<TypeTag>::beginTimeStep()
81 for (
auto& aquifer : aquifers)
82 aquifer->beginTimeStep();
85template <
typename TypeTag>
86template <
class Context>
88BlackoilAquiferModel<TypeTag>::addToSource(RateVector& rates,
89 const Context& context,
91 unsigned timeIdx)
const
93 for (
auto& aquifer : aquifers)
94 aquifer->addToSource(rates, context, spaceIdx, timeIdx);
97template <
typename TypeTag>
99BlackoilAquiferModel<TypeTag>::addToSource(RateVector& rates,
100 unsigned globalSpaceIdx,
101 unsigned timeIdx)
const
103 for (
auto& aquifer : aquifers)
104 aquifer->addToSource(rates, globalSpaceIdx, timeIdx);
107template <
typename TypeTag>
109BlackoilAquiferModel<TypeTag>::endIteration()
112template <
typename TypeTag>
114BlackoilAquiferModel<TypeTag>::endTimeStep()
116 for (
auto& aquifer : aquifers) {
117 aquifer->endTimeStep();
118 using NumAq = AquiferNumerical<TypeTag>;
119 NumAq* num =
dynamic_cast<NumAq*
>(aquifer.get());
121 this->simulator_.vanguard().grid().comm().barrier();
125template <
typename TypeTag>
127BlackoilAquiferModel<TypeTag>::endEpisode()
130template <
typename TypeTag>
131template <
class Restarter>
133BlackoilAquiferModel<TypeTag>::serialize(Restarter& )
136 throw std::logic_error(
"BlackoilAquiferModel::serialize() is not yet implemented");
139template <
typename TypeTag>
140template <
class Restarter>
142BlackoilAquiferModel<TypeTag>::deserialize(Restarter& )
145 throw std::logic_error(
"BlackoilAquiferModel::deserialize() is not yet implemented");
149template <
typename TypeTag>
150void BlackoilAquiferModel<TypeTag>::init()
152 if (this->simulator_.vanguard().eclState().aquifer().active()) {
153 this->initializeStaticAquifers();
158template<
typename TypeTag>
159data::Aquifers BlackoilAquiferModel<TypeTag>::aquiferData()
const
162 for (
const auto& aqu : this->aquifers)
163 data.insert_or_assign(aqu->aquiferID(), aqu->aquiferData());
168template<
typename TypeTag>
169template<
class Serializer>
170void BlackoilAquiferModel<TypeTag>::
171serializeOp(Serializer& serializer)
173 for (
auto& aiPtr : aquifers) {
174 auto* ct =
dynamic_cast<AquiferCarterTracy<TypeTag>*
>(aiPtr.get());
175 auto* fetp =
dynamic_cast<AquiferFetkovich<TypeTag>*
>(aiPtr.get());
176 auto* num =
dynamic_cast<AquiferNumerical<TypeTag>*
>(aiPtr.get());
177 auto* flux =
dynamic_cast<AquiferConstantFlux<TypeTag>*
>(aiPtr.get());
187 OPM_THROW(std::logic_error,
"Error serializing BlackoilAquiferModel: unknown aquifer type");
192template <
typename TypeTag>
193void BlackoilAquiferModel<TypeTag>::initializeStaticAquifers()
195 const auto& aquifer =
196 this->simulator_.vanguard().eclState().aquifer();
198 for (
const auto& aquCT : aquifer.ct()) {
199 auto aquCTPtr = this->
template createAnalyticAquiferPointer
200 <AquiferCarterTracy<TypeTag>>(aquCT, aquCT.aquiferID,
"Carter-Tracy");
202 if (aquCTPtr !=
nullptr) {
203 this->aquifers.push_back(std::move(aquCTPtr));
207 for (
const auto& aquFetp : aquifer.fetp()) {
208 auto aquFetpPtr = this->
template createAnalyticAquiferPointer
209 <AquiferFetkovich<TypeTag>>(aquFetp, aquFetp.aquiferID,
"Fetkovich");
211 if (aquFetpPtr !=
nullptr) {
212 this->aquifers.push_back(std::move(aquFetpPtr));
216 for (
const auto& [
id, aquFlux] : aquifer.aquflux()) {
218 if (! aquFlux.active) {
continue; }
220 auto aquFluxPtr = this->
template createAnalyticAquiferPointer
221 <AquiferConstantFlux<TypeTag>>(aquFlux, id,
"Constant Flux");
223 if (aquFluxPtr !=
nullptr) {
224 this->aquifers.push_back(std::move(aquFluxPtr));
228 if (aquifer.hasNumericalAquifer()) {
229 for (
const auto& aquNum : aquifer.numericalAquifers().aquifers()) {
230 auto aquNumPtr = std::make_unique<AquiferNumerical<TypeTag>>
231 (aquNum.second, this->simulator_);
233 this->aquifers.push_back(std::move(aquNumPtr));
238template <
typename TypeTag>
239template <
typename AquiferType,
typename AquiferData>
240std::unique_ptr<AquiferType>
241BlackoilAquiferModel<TypeTag>::
242createAnalyticAquiferPointer(
const AquiferData& aqData,
244 std::string_view aqType)
const
246 const auto& connections =
247 this->simulator_.vanguard().eclState().aquifer().connections();
249 if (! connections.hasAquiferConnections(aquiferID)) {
250 const auto msg = fmt::format(
"No valid connections for {} aquifer {}. "
251 "Aquifer {} will be ignored.",
252 aqType, aquiferID, aquiferID);
253 OpmLog::warning(msg);
258 return std::make_unique<AquiferType>
259 (connections.getConnections(aquiferID), this->simulator_, aqData);
262template <
typename TypeTag>
263void BlackoilAquiferModel<TypeTag>::createDynamicAquifers(
const int episode_index)
265 const auto& sched = this->simulator_.vanguard().schedule()[episode_index];
267 for (
const auto& [
id, aquFlux] : sched.aqufluxs) {
269 std::find_if(std::begin(this->aquifers),
270 std::end(this->aquifers),
271 [
id =
id](
const auto& aquPtr)
273 return aquPtr->aquiferID() ==
id;
276 if (aquPos == std::end(this->aquifers)) {
279 auto aquFluxPtr = this->
template createAnalyticAquiferPointer
280 <AquiferConstantFlux<TypeTag>>(aquFlux, id,
"Constant Flux");
282 if (aquFluxPtr !=
nullptr) {
283 this->aquifers.push_back(std::move(aquFluxPtr));
287 auto aquFluxPtr =
dynamic_cast<AquiferConstantFlux<TypeTag>*
>(aquPos->get());
288 if (aquFluxPtr ==
nullptr) {
292 fmt::format(
"Aquifer {} is updated with constant flux "
293 "aquifer keyword AQUFLUX at report step {}, "
294 "while it might be specified to be a "
295 "different type of aquifer before this. "
296 "We do not support the conversion between "
297 "different types of aquifer.\n",
id, episode_index);
299 OPM_THROW(std::runtime_error, msg);
302 aquFluxPtr->updateAquifer(aquFlux);
This file contains a set of helper functions used by VFPProd / VFPInj.
Definition: BlackoilPhases.hpp:27