From 303889516fd92905dd0c029451535785c42055cd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?B=C3=A5rd=20Skaflestad?= Date: Tue, 7 Mar 2023 18:56:33 +0100 Subject: [PATCH] Load Constant Flux Aquifer Objects from Restart File This commit adds logic and structures for bringing in constant flux aquifer objects-keyword AQUFLUX-from the restart file and forming the requisite dynamic objects in the Schedule. In particular, the 'RstAquifer' gets a new bare-bones representation of these aquifer types and we add new constant flux aquifer objects to the pertinent 'ScheduleState' when these exist. We also add this aquifer type to 'data::Aquifers' in preparation of reinitialising the simulator's aquifer container from the restart file. In particular, this needs the total produced volume from the aquifer so far. --- .../EclipseState/Aquifer/AquiferFlux.hpp | 6 +- opm/io/eclipse/rst/aquifer.hpp | 8 +++ opm/output/data/Aquifer.hpp | 2 +- .../EclipseState/Aquifer/AquiferFlux.cpp | 3 +- src/opm/input/eclipse/Schedule/Schedule.cpp | 14 +++- src/opm/io/eclipse/rst/aquifer.cpp | 71 ++++++++++++++++--- src/opm/output/eclipse/LoadRestart.cpp | 17 ++--- 7 files changed, 98 insertions(+), 23 deletions(-) diff --git a/opm/input/eclipse/EclipseState/Aquifer/AquiferFlux.hpp b/opm/input/eclipse/EclipseState/Aquifer/AquiferFlux.hpp index 2eabc4ddd..32762acf6 100644 --- a/opm/input/eclipse/EclipseState/Aquifer/AquiferFlux.hpp +++ b/opm/input/eclipse/EclipseState/Aquifer/AquiferFlux.hpp @@ -30,9 +30,9 @@ namespace Opm { class DeckRecord; } -namespace Opm::RestartIO { - class RstAquifer; -} // Opm::RestartIO +namespace Opm { namespace RestartIO { + class RstAquifer; +}} // Opm::RestartIO namespace Opm { struct SingleAquiferFlux diff --git a/opm/io/eclipse/rst/aquifer.hpp b/opm/io/eclipse/rst/aquifer.hpp index 229e8dfb2..2b4ebba75 100644 --- a/opm/io/eclipse/rst/aquifer.hpp +++ b/opm/io/eclipse/rst/aquifer.hpp @@ -77,6 +77,12 @@ namespace Opm { namespace RestartIO { double time_constant{}; }; + struct ConstantFlux { + int aquiferID{}; + + double flow_rate{}; + }; + class Connections { public: struct Cell { @@ -120,6 +126,7 @@ namespace Opm { namespace RestartIO { bool hasAnalyticAquifers() const; const std::vector& carterTracy() const; + const std::vector& constantFlux() const; const std::vector& fetkovich() const; const std::unordered_map& connections() const; @@ -127,6 +134,7 @@ namespace Opm { namespace RestartIO { class Implementation; std::unique_ptr pImpl_; }; + }} // Opm::RestartIO #endif // OPM_RESTART_AQUIFER_HPP diff --git a/opm/output/data/Aquifer.hpp b/opm/output/data/Aquifer.hpp index e6174dd69..93eb6902e 100644 --- a/opm/output/data/Aquifer.hpp +++ b/opm/output/data/Aquifer.hpp @@ -33,7 +33,7 @@ namespace Opm { namespace data { enum class AquiferType { - Fetkovich, CarterTracy, Numerical, + Fetkovich, CarterTracy, ConstantFlux, Numerical, }; struct FetkovichData diff --git a/src/opm/input/eclipse/EclipseState/Aquifer/AquiferFlux.cpp b/src/opm/input/eclipse/EclipseState/Aquifer/AquiferFlux.cpp index 461be9362..619fcf1eb 100644 --- a/src/opm/input/eclipse/EclipseState/Aquifer/AquiferFlux.cpp +++ b/src/opm/input/eclipse/EclipseState/Aquifer/AquiferFlux.cpp @@ -116,7 +116,8 @@ namespace Opm { } void AquiferFlux::loadFromRestart(const RestartIO::RstAquifer&) { - // TODO: adding the restart functionality + // Constant flux aquifer objects loaded from restart file added to + // Schedule only. } AquiferFlux AquiferFlux::serializationTestObject() { diff --git a/src/opm/input/eclipse/Schedule/Schedule.cpp b/src/opm/input/eclipse/Schedule/Schedule.cpp index 7971f2d51..2680b90ea 100644 --- a/src/opm/input/eclipse/Schedule/Schedule.cpp +++ b/src/opm/input/eclipse/Schedule/Schedule.cpp @@ -1745,7 +1745,10 @@ namespace { } } - void Schedule::load_rst(const RestartIO::RstState& rst_state, const TracerConfig& tracer_config, const ScheduleGrid& grid, const FieldPropsManager& fp) + void Schedule::load_rst(const RestartIO::RstState& rst_state, + const TracerConfig& tracer_config, + const ScheduleGrid& grid, + const FieldPropsManager& fp) { const auto report_step = rst_state.header.report_step - 1; double udq_undefined = 0; @@ -1917,6 +1920,15 @@ namespace { this->snapshots.back().network_balance.update(Network::Balance { rst_state.netbalan }); + for (const auto& aquflux : rst_state.aquifers.constantFlux()) { + auto aqPos = this->snapshots.back().aqufluxs + .insert_or_assign(aquflux.aquiferID, + SingleAquiferFlux { aquflux.aquiferID }); + + aqPos.first->second.flux = aquflux.flow_rate; + aqPos.first->second.active = true; + } + if (!rst_state.wlists.empty()) this->snapshots.back().wlist_manager.update( WListManager(rst_state) ); diff --git a/src/opm/io/eclipse/rst/aquifer.cpp b/src/opm/io/eclipse/rst/aquifer.cpp index fa999f63a..0ee459d35 100644 --- a/src/opm/io/eclipse/rst/aquifer.cpp +++ b/src/opm/io/eclipse/rst/aquifer.cpp @@ -385,6 +385,30 @@ load_carter_tracy(const int aquiferID, // --------------------------------------------------------------------- +Opm::RestartIO::RstAquifer::ConstantFlux +load_constant_flux(const int aquiferID, + const AquiferVectors& aquifers, + const Opm::UnitSystem& usys) +{ + auto aquifer = Opm::RestartIO::RstAquifer::ConstantFlux{}; + + using M = Opm::UnitSystem::measure; + using Ix = VI::SAnalyticAquifer::index; + + const auto saaq = aquifers.saaq(aquiferID); + + const auto q = usys.to_si(M::liquid_surface_rate, saaq[Ix::ConstFluxValue]); + + aquifer.aquiferID = aquiferID + 1; + + // Unit hack: *from_si()* here since we don't have an area unit. + aquifer.flow_rate = usys.from_si(M::length, usys.from_si(M::length, q)); + + return aquifer; +} + +// --------------------------------------------------------------------- + Opm::RestartIO::RstAquifer::Fetkovich load_fetkovich(const int aquiferID, const AquiferVectors& aquifers, @@ -490,9 +514,10 @@ public: bool hasAnalyticAquifers() const { - return ! (this->connections_.empty() && - this->carterTracy_.empty() && - this->fetkovich_ .empty()); + return ! (this->connections_ .empty() && + this->carterTracy_ .empty() && + this->constantFlux_.empty() && + this->fetkovich_ .empty()); } const std::vector& carterTracy() const @@ -500,6 +525,11 @@ public: return this->carterTracy_; } + const std::vector& constantFlux() const + { + return this->constantFlux_; + } + const std::vector& fetkovich() const { return this->fetkovich_; @@ -513,6 +543,7 @@ public: private: std::unordered_map connections_{}; std::vector carterTracy_{}; + std::vector constantFlux_{}; std::vector fetkovich_{}; void loadAnalyticAquiferConnections(const AquiferVectors& vectors, @@ -530,6 +561,10 @@ private: const AquiferVectors& aquifers, const UnitSystem& usys); + void loadConstantFlux(const int aquiferID, + const AquiferVectors& aquifers, + const UnitSystem& usys); + void loadFetkovich(const int aquiferID, const AquiferVectors& aquifers, const UnitSystem& usys); @@ -559,7 +594,7 @@ loadAnalyticAquiferConnections(const AquiferVectors& aquifers, const UnitSystem& usys) { const auto occurence = ConnectionOccurrence { aquifers.maxAquiferID(), *rstView }; - const auto connections = ConnectionVectors { rstView->intehead(), std::move(rstView) }; + const auto connections = ConnectionVectors { rstView->intehead(), rstView }; this->connections_ = load_aquifer_connections(occurence, aquifers, connections, @@ -597,6 +632,10 @@ loadAnalyticAquifer(const int aquiferID, this->loadCarterTracy(aquiferID, aquifers, usys); return; + case VI::IAnalyticAquifer::Value::ModelType::ConstantFlux: + this->loadConstantFlux(aquiferID, aquifers, usys); + return; + case VI::IAnalyticAquifer::Value::ModelType::Fetkovich: this->loadFetkovich(aquiferID, aquifers, usys); return; @@ -617,6 +656,15 @@ loadCarterTracy(const int aquiferID, this->carterTracy_.push_back(load_carter_tracy(aquiferID, aquifers, usys)); } +void +Opm::RestartIO::RstAquifer::Implementation:: +loadConstantFlux(const int aquiferID, + const AquiferVectors& aquifers, + const UnitSystem& usys) +{ + this->constantFlux_.push_back(load_constant_flux(aquiferID, aquifers, usys)); +} + void Opm::RestartIO::RstAquifer::Implementation:: loadFetkovich(const int aquiferID, @@ -631,11 +679,11 @@ loadFetkovich(const int aquiferID, Opm::RestartIO::RstAquifer::RstAquifer(std::shared_ptr rstView, const EclipseGrid* grid, const UnitSystem& usys) - : pImpl_{ new Implementation{ std::move(rstView), grid, usys } } + : pImpl_{ std::make_unique(std::move(rstView), grid, usys) } {} Opm::RestartIO::RstAquifer::RstAquifer(const RstAquifer& rhs) - : pImpl_{ new Implementation{ *rhs.pImpl_ } } + : pImpl_{ std::make_unique(*rhs.pImpl_) } {} Opm::RestartIO::RstAquifer::RstAquifer(RstAquifer&& rhs) @@ -645,7 +693,7 @@ Opm::RestartIO::RstAquifer::RstAquifer(RstAquifer&& rhs) Opm::RestartIO::RstAquifer& Opm::RestartIO::RstAquifer::operator=(const RstAquifer& rhs) { - this->pImpl_.reset(new Implementation{ *rhs.pImpl_ }); + this->pImpl_ = std::make_unique(*rhs.pImpl_); return *this; } @@ -656,8 +704,7 @@ Opm::RestartIO::RstAquifer::operator=(RstAquifer&& rhs) return *this; } -Opm::RestartIO::RstAquifer::~RstAquifer() -{} +Opm::RestartIO::RstAquifer::~RstAquifer() = default; bool Opm::RestartIO::RstAquifer::hasAnalyticAquifers() const { @@ -670,6 +717,12 @@ Opm::RestartIO::RstAquifer::carterTracy() const return this->pImpl_->carterTracy(); } +const std::vector& +Opm::RestartIO::RstAquifer::constantFlux() const +{ + return this->pImpl_->constantFlux(); +} + const std::vector& Opm::RestartIO::RstAquifer::fetkovich() const { diff --git a/src/opm/output/eclipse/LoadRestart.cpp b/src/opm/output/eclipse/LoadRestart.cpp index 883744671..0bd1be413 100644 --- a/src/opm/output/eclipse/LoadRestart.cpp +++ b/src/opm/output/eclipse/LoadRestart.cpp @@ -1316,19 +1316,20 @@ namespace { Opm::data::AquiferType determineAquiferType(const AquiferVectors::Window& iaaq) { - const auto t1 = iaaq[VI::IAnalyticAquifer::TypeRelated1]; + using MType = Opm::RestartIO::Helpers::VectorItems:: + IAnalyticAquifer::Value::ModelType; - if (t1 == 1) { - return Opm::data::AquiferType::CarterTracy; - } + using AType = Opm::data::AquiferType; - if (t1 == 0) { - return Opm::data::AquiferType::Fetkovich; + switch (iaaq[VI::IAnalyticAquifer::TypeRelated1]) { + case MType::Fetkovich: return AType::Fetkovich; + case MType::CarterTracy: return AType::CarterTracy; + case MType::ConstantFlux: return AType::ConstantFlux; } throw std::runtime_error { - "Unknown Aquifer Type:" - " T1 = " + std::to_string(t1) + "Unknown Aquifer Type: T1 = " + + std::to_string(iaaq[VI::IAnalyticAquifer::TypeRelated1]) }; }