20#ifndef OPM_BLACKOILAQUIFERMODEL_IMPL_HEADER_INCLUDED
21#define OPM_BLACKOILAQUIFERMODEL_IMPL_HEADER_INCLUDED
24#ifndef OPM_BLACKOILAQUIFERMODEL_HEADER_INCLUDED
31#include <opm/common/ErrorMacros.hpp>
33#include <fmt/format.h>
43template <
typename TypeTag>
45 : simulator_(simulator)
48 using Grid = std::remove_const_t<std::remove_reference_t<
decltype(simulator.vanguard().grid())>>;
54template <
typename TypeTag>
58 this->computeConnectionAreaFraction();
60 for (
auto& aquifer : this->aquifers) {
61 aquifer->initialSolutionApplied();
65template <
typename TypeTag>
69 this->computeConnectionAreaFraction();
71 for (
auto& aquifer : this->aquifers) {
72 aquifer->initFromRestart(aquiferSoln);
76template <
typename TypeTag>
85 this->createDynamicAquifers(this->simulator_.episodeIndex());
87 this->computeConnectionAreaFraction();
90template <
typename TypeTag>
95template <
typename TypeTag>
99 for (
auto& aquifer : this->aquifers) {
100 aquifer->beginTimeStep();
104template <
typename TypeTag>
105template <
class Context>
108 const Context& context,
110 unsigned timeIdx)
const
112 for (
auto& aquifer : this->aquifers) {
113 aquifer->addToSource(rates, context, spaceIdx, timeIdx);
117template <
typename TypeTag>
120 unsigned globalSpaceIdx,
121 unsigned timeIdx)
const
123 for (
auto& aquifer : this->aquifers) {
124 aquifer->addToSource(rates, globalSpaceIdx, timeIdx);
128template <
typename TypeTag>
129typename BlackoilAquiferModel<TypeTag>::Scalar
133 for (
const auto& aquifer : this->aquifers) {
134 rate += aquifer->cachedConnectionInfluxRate(globalSpaceIdx);
139template <
typename TypeTag>
144template <
typename TypeTag>
150 for (
const auto& aquifer : this->aquifers) {
152 const NumAq* num =
dynamic_cast<const NumAq*
>(aquifer.get());
154 this->simulator_.vanguard().grid().comm().barrier();
159template <
typename TypeTag>
164template <
typename TypeTag>
165template <
class Restarter>
170 throw std::logic_error(
"BlackoilAquiferModel::serialize() is not yet implemented");
173template <
typename TypeTag>
174template <
class Restarter>
179 throw std::logic_error(
"BlackoilAquiferModel::deserialize() is not yet implemented");
183template <
typename TypeTag>
186 if (this->simulator_.vanguard().eclState().aquifer().active()) {
187 this->initializeStaticAquifers();
190 if (this->needRestartDynamicAquifers()) {
191 this->initializeRestartDynamicAquifers();
195template<
typename TypeTag>
199 for (
const auto& aqu : this->aquifers) {
200 data.insert_or_assign(aqu->aquiferID(), aqu->aquiferData());
206template<
typename TypeTag>
207template<
class Serializer>
211 for (
auto& aiPtr : this->aquifers) {
225 OPM_THROW(std::logic_error,
"Error serializing BlackoilAquiferModel: unknown aquifer type");
230template <
typename TypeTag>
233 const auto rstStep = this->simulator_.vanguard().eclState()
234 .getInitConfig().getRestartStep() - 1;
236 this->createDynamicAquifers(rstStep);
239template <
typename TypeTag>
240void BlackoilAquiferModel<TypeTag>::initializeStaticAquifers()
242 const auto& aquifer =
243 this->simulator_.vanguard().eclState().aquifer();
245 for (
const auto& aquCT : aquifer.ct()) {
246 auto aquCTPtr = this->
template createAnalyticAquiferPointer
247 <AquiferCarterTracy<TypeTag>>(aquCT, aquCT.aquiferID,
"Carter-Tracy");
249 if (aquCTPtr !=
nullptr) {
250 this->aquifers.push_back(std::move(aquCTPtr));
254 for (
const auto& aquFetp : aquifer.fetp()) {
255 auto aquFetpPtr = this->
template createAnalyticAquiferPointer
256 <AquiferFetkovich<TypeTag>>(aquFetp, aquFetp.aquiferID,
"Fetkovich");
258 if (aquFetpPtr !=
nullptr) {
259 this->aquifers.push_back(std::move(aquFetpPtr));
263 for (
const auto& [
id, aquFlux] : aquifer.aquflux()) {
265 if (! aquFlux.active) {
continue; }
267 auto aquFluxPtr = this->
template createAnalyticAquiferPointer
268 <AquiferConstantFlux<TypeTag>>(aquFlux, id,
"Constant Flux");
270 if (aquFluxPtr !=
nullptr) {
271 this->aquifers.push_back(std::move(aquFluxPtr));
275 if (aquifer.hasNumericalAquifer()) {
276 for (
const auto& aquNum : aquifer.numericalAquifers().aquifers()) {
277 auto aquNumPtr = std::make_unique<AquiferNumerical<TypeTag>>
278 (aquNum.second, this->simulator_);
280 this->aquifers.push_back(std::move(aquNumPtr));
285template <
typename TypeTag>
286bool BlackoilAquiferModel<TypeTag>::needRestartDynamicAquifers()
const
288 const auto& initconfig =
289 this->simulator_.vanguard().eclState().getInitConfig();
291 if (! initconfig.restartRequested()) {
295 return this->simulator_.vanguard()
296 .schedule()[initconfig.getRestartStep() - 1].hasAnalyticalAquifers();
299template <
typename TypeTag>
300template <
typename AquiferType,
typename AquiferData>
301std::unique_ptr<AquiferType>
302BlackoilAquiferModel<TypeTag>::
303createAnalyticAquiferPointer(
const AquiferData& aqData,
305 std::string_view aqType)
const
307 const auto& connections =
308 this->simulator_.vanguard().eclState().aquifer().connections();
310 if (! connections.hasAquiferConnections(aquiferID)) {
311 const auto msg = fmt::format(fmt::runtime(
"No valid connections for {} aquifer {}. "
312 "Aquifer {} will be ignored."),
313 aqType, aquiferID, aquiferID);
314 OpmLog::warning(msg);
319 return std::make_unique<AquiferType>
320 (connections.getConnections(aquiferID), this->simulator_, aqData);
323template <
typename TypeTag>
324void BlackoilAquiferModel<TypeTag>::createDynamicAquifers(
const int episode_index)
326 const auto& sched = this->simulator_.vanguard().schedule()[episode_index];
328 for (
const auto& [
id, aquFlux] : sched.aqufluxs) {
330 std::ranges::find_if(this->aquifers,
331 [Id =
id](
const auto& aquPtr)
332 {
return aquPtr->aquiferID() == Id; });
334 if (aquPos == std::end(this->aquifers)) {
337 auto aquFluxPtr = this->
template createAnalyticAquiferPointer
338 <AquiferConstantFlux<TypeTag>>(aquFlux, id,
"Constant Flux");
340 if (aquFluxPtr !=
nullptr) {
341 this->aquifers.push_back(std::move(aquFluxPtr));
345 auto aquFluxPtr =
dynamic_cast<AquiferConstantFlux<TypeTag>*
>(aquPos->get());
346 if (aquFluxPtr ==
nullptr) {
350 fmt::format(
"Aquifer {} is updated with constant flux "
351 "aquifer keyword AQUFLUX at report step {}, "
352 "while it might be specified to be a "
353 "different type of aquifer before this. "
354 "We do not support the conversion between "
355 "different types of aquifer.\n",
id, episode_index);
357 OPM_THROW(std::runtime_error, msg);
360 aquFluxPtr->updateAquifer(aquFlux);
365template <
typename TypeTag>
366void BlackoilAquiferModel<TypeTag>::computeConnectionAreaFraction()
const
369 std::accumulate(this->aquifers.begin(), this->aquifers.end(), 0,
370 [](
const int aquID,
const auto& aquifer)
371 { return std::max(aquID, aquifer->aquiferID()); });
373 maxAquID = this->simulator_.vanguard().grid().comm().max(maxAquID);
375 auto totalConnArea = std::vector<Scalar>(maxAquID, 0.0);
376 for (
const auto& aquifer : this->aquifers) {
377 totalConnArea[aquifer->aquiferID() - 1] += aquifer->totalFaceArea();
380 this->simulator_.vanguard().grid().comm().sum(totalConnArea.data(), maxAquID);
382 for (
auto& aquifer : this->aquifers) {
383 aquifer->computeFaceAreaFraction(totalConnArea);
Definition: AquiferCarterTracy.hpp:42
Definition: AquiferConstantFlux.hpp:39
Definition: AquiferFetkovich.hpp:38
Definition: AquiferNumerical.hpp:45
void endTimeStep() override
Definition: AquiferNumerical.hpp:127
Class for handling the blackoil aquifer model.
Definition: BlackoilAquiferModel.hpp:50
void beginTimeStep()
Definition: BlackoilAquiferModel_impl.hpp:97
void initFromRestart(const data::Aquifers &aquiferSoln)
Definition: BlackoilAquiferModel_impl.hpp:67
BlackoilAquiferModel(Simulator &simulator)
Definition: BlackoilAquiferModel_impl.hpp:44
void init()
Definition: BlackoilAquiferModel_impl.hpp:184
void endEpisode()
Definition: BlackoilAquiferModel_impl.hpp:161
void endTimeStep()
Definition: BlackoilAquiferModel_impl.hpp:146
void serializeOp(Serializer &serializer)
Definition: BlackoilAquiferModel_impl.hpp:209
void deserialize(Restarter &res)
Definition: BlackoilAquiferModel_impl.hpp:176
data::Aquifers aquiferData() const
Definition: BlackoilAquiferModel_impl.hpp:196
Scalar cachedConnectionInfluxRate(unsigned globalSpaceIdx) const
Definition: BlackoilAquiferModel_impl.hpp:130
void serialize(Restarter &res)
Definition: BlackoilAquiferModel_impl.hpp:167
void beginIteration()
Definition: BlackoilAquiferModel_impl.hpp:92
void addToSource(RateVector &rates, const Context &context, unsigned spaceIdx, unsigned timeIdx) const
Definition: BlackoilAquiferModel_impl.hpp:107
void initialSolutionApplied()
Definition: BlackoilAquiferModel_impl.hpp:56
void endIteration()
Definition: BlackoilAquiferModel_impl.hpp:141
void beginEpisode()
Definition: BlackoilAquiferModel_impl.hpp:78
Definition: SupportsFaceTag.hpp:34
Definition: blackoilbioeffectsmodules.hh:45