22#ifndef OPM_BLACKOILAQUIFERMODEL_HEADER_INCLUDED
24#define OPM_BLACKOILAQUIFERMODEL_IMPL_HEADER_INCLUDED
30#include <opm/common/ErrorMacros.hpp>
32#include <fmt/format.h>
42template <
typename TypeTag>
44 : simulator_(simulator)
47 using Grid = std::remove_const_t<std::remove_reference_t<
decltype(simulator.vanguard().grid())>>;
53template <
typename TypeTag>
57 this->computeConnectionAreaFraction();
59 for (
auto& aquifer : this->aquifers) {
60 aquifer->initialSolutionApplied();
64template <
typename TypeTag>
68 this->computeConnectionAreaFraction();
70 for (
auto& aquifer : this->aquifers) {
71 aquifer->initFromRestart(aquiferSoln);
75template <
typename TypeTag>
84 this->createDynamicAquifers(this->simulator_.episodeIndex());
86 this->computeConnectionAreaFraction();
89template <
typename TypeTag>
94template <
typename TypeTag>
98 for (
auto& aquifer : this->aquifers) {
99 aquifer->beginTimeStep();
103template <
typename TypeTag>
104template <
class Context>
107 const Context& context,
109 unsigned timeIdx)
const
111 for (
auto& aquifer : this->aquifers) {
112 aquifer->addToSource(rates, context, spaceIdx, timeIdx);
116template <
typename TypeTag>
119 unsigned globalSpaceIdx,
120 unsigned timeIdx)
const
122 for (
auto& aquifer : this->aquifers) {
123 aquifer->addToSource(rates, globalSpaceIdx, timeIdx);
127template <
typename TypeTag>
132template <
typename TypeTag>
138 for (
auto& aquifer : this->aquifers) {
140 NumAq* num =
dynamic_cast<NumAq*
>(aquifer.get());
142 this->simulator_.vanguard().grid().comm().barrier();
146template <
typename TypeTag>
151template <
typename TypeTag>
152template <
class Restarter>
157 throw std::logic_error(
"BlackoilAquiferModel::serialize() is not yet implemented");
160template <
typename TypeTag>
161template <
class Restarter>
166 throw std::logic_error(
"BlackoilAquiferModel::deserialize() is not yet implemented");
170template <
typename TypeTag>
173 if (this->simulator_.vanguard().eclState().aquifer().active()) {
174 this->initializeStaticAquifers();
177 if (this->needRestartDynamicAquifers()) {
178 this->initializeRestartDynamicAquifers();
182template<
typename TypeTag>
186 for (
const auto& aqu : this->aquifers) {
187 data.insert_or_assign(aqu->aquiferID(), aqu->aquiferData());
193template<
typename TypeTag>
194template<
class Serializer>
198 for (
auto& aiPtr : this->aquifers) {
212 OPM_THROW(std::logic_error,
"Error serializing BlackoilAquiferModel: unknown aquifer type");
217template <
typename TypeTag>
220 const auto rstStep = this->simulator_.vanguard().eclState()
221 .getInitConfig().getRestartStep() - 1;
223 this->createDynamicAquifers(rstStep);
226template <
typename TypeTag>
227void BlackoilAquiferModel<TypeTag>::initializeStaticAquifers()
229 const auto& aquifer =
230 this->simulator_.vanguard().eclState().aquifer();
232 for (
const auto& aquCT : aquifer.ct()) {
233 auto aquCTPtr = this->
template createAnalyticAquiferPointer
234 <AquiferCarterTracy<TypeTag>>(aquCT, aquCT.aquiferID,
"Carter-Tracy");
236 if (aquCTPtr !=
nullptr) {
237 this->aquifers.push_back(std::move(aquCTPtr));
241 for (
const auto& aquFetp : aquifer.fetp()) {
242 auto aquFetpPtr = this->
template createAnalyticAquiferPointer
243 <AquiferFetkovich<TypeTag>>(aquFetp, aquFetp.aquiferID,
"Fetkovich");
245 if (aquFetpPtr !=
nullptr) {
246 this->aquifers.push_back(std::move(aquFetpPtr));
250 for (
const auto& [
id, aquFlux] : aquifer.aquflux()) {
252 if (! aquFlux.active) {
continue; }
254 auto aquFluxPtr = this->
template createAnalyticAquiferPointer
255 <AquiferConstantFlux<TypeTag>>(aquFlux, id,
"Constant Flux");
257 if (aquFluxPtr !=
nullptr) {
258 this->aquifers.push_back(std::move(aquFluxPtr));
262 if (aquifer.hasNumericalAquifer()) {
263 for (
const auto& aquNum : aquifer.numericalAquifers().aquifers()) {
264 auto aquNumPtr = std::make_unique<AquiferNumerical<TypeTag>>
265 (aquNum.second, this->simulator_);
267 this->aquifers.push_back(std::move(aquNumPtr));
272template <
typename TypeTag>
273bool BlackoilAquiferModel<TypeTag>::needRestartDynamicAquifers()
const
275 const auto& initconfig =
276 this->simulator_.vanguard().eclState().getInitConfig();
278 if (! initconfig.restartRequested()) {
282 return this->simulator_.vanguard()
283 .schedule()[initconfig.getRestartStep() - 1].hasAnalyticalAquifers();
286template <
typename TypeTag>
287template <
typename AquiferType,
typename AquiferData>
288std::unique_ptr<AquiferType>
289BlackoilAquiferModel<TypeTag>::
290createAnalyticAquiferPointer(
const AquiferData& aqData,
292 std::string_view aqType)
const
294 const auto& connections =
295 this->simulator_.vanguard().eclState().aquifer().connections();
297 if (! connections.hasAquiferConnections(aquiferID)) {
298 const auto msg = fmt::format(
"No valid connections for {} aquifer {}. "
299 "Aquifer {} will be ignored.",
300 aqType, aquiferID, aquiferID);
301 OpmLog::warning(msg);
306 return std::make_unique<AquiferType>
307 (connections.getConnections(aquiferID), this->simulator_, aqData);
310template <
typename TypeTag>
311void BlackoilAquiferModel<TypeTag>::createDynamicAquifers(
const int episode_index)
313 const auto& sched = this->simulator_.vanguard().schedule()[episode_index];
315 for (
const auto& [
id, aquFlux] : sched.aqufluxs) {
317 std::find_if(std::begin(this->aquifers),
318 std::end(this->aquifers),
319 [
id =
id](
const auto& aquPtr)
321 return aquPtr->aquiferID() ==
id;
324 if (aquPos == std::end(this->aquifers)) {
327 auto aquFluxPtr = this->
template createAnalyticAquiferPointer
328 <AquiferConstantFlux<TypeTag>>(aquFlux, id,
"Constant Flux");
330 if (aquFluxPtr !=
nullptr) {
331 this->aquifers.push_back(std::move(aquFluxPtr));
335 auto aquFluxPtr =
dynamic_cast<AquiferConstantFlux<TypeTag>*
>(aquPos->get());
336 if (aquFluxPtr ==
nullptr) {
340 fmt::format(
"Aquifer {} is updated with constant flux "
341 "aquifer keyword AQUFLUX at report step {}, "
342 "while it might be specified to be a "
343 "different type of aquifer before this. "
344 "We do not support the conversion between "
345 "different types of aquifer.\n",
id, episode_index);
347 OPM_THROW(std::runtime_error, msg);
350 aquFluxPtr->updateAquifer(aquFlux);
355template <
typename TypeTag>
356void BlackoilAquiferModel<TypeTag>::computeConnectionAreaFraction()
const
359 std::accumulate(this->aquifers.begin(), this->aquifers.end(), 0,
360 [](
const int aquID,
const auto& aquifer)
361 { return std::max(aquID, aquifer->aquiferID()); });
363 maxAquID = this->simulator_.vanguard().grid().comm().max(maxAquID);
365 auto totalConnArea = std::vector<Scalar>(maxAquID, 0.0);
366 for (
const auto& aquifer : this->aquifers) {
367 totalConnArea[aquifer->aquiferID() - 1] += aquifer->totalFaceArea();
370 this->simulator_.vanguard().grid().comm().sum(totalConnArea.data(), maxAquID);
372 for (
auto& aquifer : this->aquifers) {
373 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:129
Class for handling the blackoil aquifer model.
Definition: BlackoilAquiferModel.hpp:50
void beginTimeStep()
Definition: BlackoilAquiferModel_impl.hpp:96
void initFromRestart(const data::Aquifers &aquiferSoln)
Definition: BlackoilAquiferModel_impl.hpp:66
BlackoilAquiferModel(Simulator &simulator)
Definition: BlackoilAquiferModel_impl.hpp:43
void init()
Definition: BlackoilAquiferModel_impl.hpp:171
void endEpisode()
Definition: BlackoilAquiferModel_impl.hpp:148
void endTimeStep()
Definition: BlackoilAquiferModel_impl.hpp:134
void serializeOp(Serializer &serializer)
Definition: BlackoilAquiferModel_impl.hpp:196
void deserialize(Restarter &res)
Definition: BlackoilAquiferModel_impl.hpp:163
data::Aquifers aquiferData() const
Definition: BlackoilAquiferModel_impl.hpp:183
void serialize(Restarter &res)
Definition: BlackoilAquiferModel_impl.hpp:154
void beginIteration()
Definition: BlackoilAquiferModel_impl.hpp:91
void addToSource(RateVector &rates, const Context &context, unsigned spaceIdx, unsigned timeIdx) const
Definition: BlackoilAquiferModel_impl.hpp:106
void initialSolutionApplied()
Definition: BlackoilAquiferModel_impl.hpp:55
void endIteration()
Definition: BlackoilAquiferModel_impl.hpp:129
void beginEpisode()
Definition: BlackoilAquiferModel_impl.hpp:77
Definition: SupportsFaceTag.hpp:34
Definition: blackoilboundaryratevector.hh:37