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>
 
  133template <
typename TypeTag>
 
  139    for (
const auto& aquifer : this->aquifers) {
 
  141        const NumAq* num = 
dynamic_cast<const NumAq*
>(aquifer.get());
 
  143            this->simulator_.vanguard().grid().comm().barrier();
 
  148template <
typename TypeTag>
 
  153template <
typename TypeTag>
 
  154template <
class Restarter>
 
  159    throw std::logic_error(
"BlackoilAquiferModel::serialize() is not yet implemented");
 
  162template <
typename TypeTag>
 
  163template <
class Restarter>
 
  168    throw std::logic_error(
"BlackoilAquiferModel::deserialize() is not yet implemented");
 
  172template <
typename TypeTag>
 
  175    if (this->simulator_.vanguard().eclState().aquifer().active()) {
 
  176        this->initializeStaticAquifers();
 
  179    if (this->needRestartDynamicAquifers()) {
 
  180        this->initializeRestartDynamicAquifers();
 
  184template<
typename TypeTag>
 
  188    for (
const auto& aqu : this->aquifers) {
 
  189        data.insert_or_assign(aqu->aquiferID(), aqu->aquiferData());
 
  195template<
typename TypeTag>
 
  196template<
class Serializer>
 
  200    for (
auto& aiPtr : this->aquifers) {
 
  214            OPM_THROW(std::logic_error, 
"Error serializing BlackoilAquiferModel: unknown aquifer type");
 
  219template <
typename TypeTag>
 
  222    const auto rstStep = this->simulator_.vanguard().eclState()
 
  223        .getInitConfig().getRestartStep() - 1;
 
  225    this->createDynamicAquifers(rstStep);
 
  228template <
typename TypeTag>
 
  229void BlackoilAquiferModel<TypeTag>::initializeStaticAquifers()
 
  231    const auto& aquifer =
 
  232        this->simulator_.vanguard().eclState().aquifer();
 
  234    for (
const auto& aquCT : aquifer.ct()) {
 
  235        auto aquCTPtr = this->
template createAnalyticAquiferPointer
 
  236            <AquiferCarterTracy<TypeTag>>(aquCT, aquCT.aquiferID, 
"Carter-Tracy");
 
  238        if (aquCTPtr != 
nullptr) {
 
  239            this->aquifers.push_back(std::move(aquCTPtr));
 
  243    for (
const auto& aquFetp : aquifer.fetp()) {
 
  244        auto aquFetpPtr = this->
template createAnalyticAquiferPointer
 
  245            <AquiferFetkovich<TypeTag>>(aquFetp, aquFetp.aquiferID, 
"Fetkovich");
 
  247        if (aquFetpPtr != 
nullptr) {
 
  248            this->aquifers.push_back(std::move(aquFetpPtr));
 
  252    for (
const auto& [
id, aquFlux] : aquifer.aquflux()) {
 
  254        if (! aquFlux.active) { 
continue; }
 
  256        auto aquFluxPtr = this->
template createAnalyticAquiferPointer
 
  257            <AquiferConstantFlux<TypeTag>>(aquFlux, id, 
"Constant Flux");
 
  259        if (aquFluxPtr != 
nullptr) {
 
  260            this->aquifers.push_back(std::move(aquFluxPtr));
 
  264    if (aquifer.hasNumericalAquifer()) {
 
  265        for (
const auto& aquNum : aquifer.numericalAquifers().aquifers()) {
 
  266            auto aquNumPtr = std::make_unique<AquiferNumerical<TypeTag>>
 
  267                (aquNum.second, this->simulator_);
 
  269            this->aquifers.push_back(std::move(aquNumPtr));
 
  274template <
typename TypeTag>
 
  275bool BlackoilAquiferModel<TypeTag>::needRestartDynamicAquifers()
 const 
  277    const auto& initconfig =
 
  278        this->simulator_.vanguard().eclState().getInitConfig();
 
  280    if (! initconfig.restartRequested()) {
 
  284    return this->simulator_.vanguard()
 
  285        .schedule()[initconfig.getRestartStep() - 1].hasAnalyticalAquifers();
 
  288template <
typename TypeTag>
 
  289template <
typename AquiferType, 
typename AquiferData>
 
  290std::unique_ptr<AquiferType>
 
  291BlackoilAquiferModel<TypeTag>::
 
  292createAnalyticAquiferPointer(
const AquiferData& aqData,
 
  294                             std::string_view   aqType)
 const 
  296    const auto& connections =
 
  297        this->simulator_.vanguard().eclState().aquifer().connections();
 
  299    if (! connections.hasAquiferConnections(aquiferID)) {
 
  300        const auto msg = fmt::format(
"No valid connections for {} aquifer {}.  " 
  301                                     "Aquifer {} will be ignored.",
 
  302                                     aqType, aquiferID, aquiferID);
 
  303        OpmLog::warning(msg);
 
  308    return std::make_unique<AquiferType>
 
  309        (connections.getConnections(aquiferID), this->simulator_, aqData);
 
  312template <
typename TypeTag>
 
  313void BlackoilAquiferModel<TypeTag>::createDynamicAquifers(
const int episode_index)
 
  315    const auto& sched = this->simulator_.vanguard().schedule()[episode_index];
 
  317    for (
const auto& [
id, aquFlux] : sched.aqufluxs) {
 
  319            std::find_if(std::begin(this->aquifers),
 
  320                         std::end(this->aquifers),
 
  321                [Id = 
id](
const auto& aquPtr)
 
  323                return aquPtr->aquiferID() == Id;
 
  326        if (aquPos == std::end(this->aquifers)) {
 
  329            auto aquFluxPtr = this->
template createAnalyticAquiferPointer
 
  330                <AquiferConstantFlux<TypeTag>>(aquFlux, id, 
"Constant Flux");
 
  332            if (aquFluxPtr != 
nullptr) {
 
  333                this->aquifers.push_back(std::move(aquFluxPtr));
 
  337            auto aquFluxPtr = 
dynamic_cast<AquiferConstantFlux<TypeTag>*
>(aquPos->get());
 
  338            if (aquFluxPtr == 
nullptr) {
 
  342                    fmt::format(
"Aquifer {} is updated with constant flux " 
  343                                "aquifer keyword AQUFLUX at report step {}, " 
  344                                "while it might be specified to be a " 
  345                                "different type of aquifer before this. " 
  346                                "We do not support the conversion between " 
  347                                "different types of aquifer.\n", 
id, episode_index);
 
  349                OPM_THROW(std::runtime_error, msg);
 
  352            aquFluxPtr->updateAquifer(aquFlux);
 
  357template <
typename TypeTag>
 
  358void BlackoilAquiferModel<TypeTag>::computeConnectionAreaFraction()
 const 
  361        std::accumulate(this->aquifers.begin(), this->aquifers.end(), 0,
 
  362                        [](
const int aquID, 
const auto& aquifer)
 
  363                        { return std::max(aquID, aquifer->aquiferID()); });
 
  365    maxAquID = this->simulator_.vanguard().grid().comm().max(maxAquID);
 
  367    auto totalConnArea = std::vector<Scalar>(maxAquID, 0.0);
 
  368    for (
const auto& aquifer : this->aquifers) {
 
  369        totalConnArea[aquifer->aquiferID() - 1] += aquifer->totalFaceArea();
 
  372    this->simulator_.vanguard().grid().comm().sum(totalConnArea.data(), maxAquID);
 
  374    for (
auto& aquifer : this->aquifers) {
 
  375        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: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:173
 
void endEpisode()
Definition: BlackoilAquiferModel_impl.hpp:150
 
void endTimeStep()
Definition: BlackoilAquiferModel_impl.hpp:135
 
void serializeOp(Serializer &serializer)
Definition: BlackoilAquiferModel_impl.hpp:198
 
void deserialize(Restarter &res)
Definition: BlackoilAquiferModel_impl.hpp:165
 
data::Aquifers aquiferData() const
Definition: BlackoilAquiferModel_impl.hpp:185
 
void serialize(Restarter &res)
Definition: BlackoilAquiferModel_impl.hpp:156
 
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:130
 
void beginEpisode()
Definition: BlackoilAquiferModel_impl.hpp:78
 
Definition: SupportsFaceTag.hpp:34
 
Definition: blackoilbioeffectsmodules.hh:43