putting AQUFLUX aquifers in one class

This commit is contained in:
Kai Bao
2023-02-17 11:18:02 +01:00
parent 35b095dfbc
commit 1d8e92a262
8 changed files with 134 additions and 58 deletions

View File

@@ -45,18 +45,22 @@ namespace Opm {
class AquiferConfig {
public:
using AquFluxs = std::unordered_map<int, AquiferFlux>;
AquiferConfig() = default;
AquiferConfig(const TableManager& tables, const EclipseGrid& grid,
const Deck& deck, const FieldPropsManager& field_props);
AquiferConfig(const Aquifetp& fetp, const AquiferCT& ct, const AquFluxs& aqufluxs, const Aquancon& conn);
AquiferConfig(const Aquifetp& fetp, const AquiferCT& ct, const AquiferFlux& aqufluxs, const Aquancon& conn);
void load_connections(const Deck& deck, const EclipseGrid& grid);
void pruneDeactivatedAquiferConnections(const std::vector<std::size_t>& deactivated_cells);
void loadFromRestart(const RestartIO::RstAquifer& aquifers,
const TableManager& tables);
// there might be some aquifers (AQUFLUX only for now) are opened through
// SCHEDULE section while not specified in the SOLUTION section.
// We create dummy aquifers in the AquiferConfig to make sure we are aware of them
// when we handle the SUMMARY section.
// Since those aquifers are not active, basically we only need the id information
void appendAqufluxSchedule(const std::unordered_set<int>& ids);
static AquiferConfig serializationTestObject();
@@ -64,7 +68,7 @@ public:
bool active() const;
const AquiferCT& ct() const;
const Aquifetp& fetp() const;
const AquFluxs& aquflux() const;
const AquiferFlux& aquflux() const;
const Aquancon& connections() const;
bool operator==(const AquiferConfig& other) const;
bool hasAquifer(const int aquID) const;
@@ -88,7 +92,7 @@ public:
private:
Aquifetp aquifetp{};
AquiferCT aquiferct{};
AquFluxs aquiferflux{};
AquiferFlux aquiferflux{};
mutable NumericalAquifers numerical_aquifers{};
Aquancon aqconn{};
};

View File

@@ -22,6 +22,7 @@
#include <optional>
#include <unordered_map>
#include <unordered_set>
#include <vector>
namespace Opm {
@@ -29,26 +30,27 @@ namespace Opm {
class DeckRecord;
}
namespace Opm::RestartIO {
class RstAquifer;
} // Opm::RestartIO
namespace Opm {
struct AquiferFlux {
explicit AquiferFlux(const DeckRecord& record);
struct SingleAquiferFlux {
explicit SingleAquiferFlux(const DeckRecord& record);
// using id to create a noninactive dummy aquifer
explicit AquiferFlux(int id);
// using id to create an inactive dummy aquifer
explicit SingleAquiferFlux(int id);
SingleAquiferFlux() = default;
SingleAquiferFlux(int id, double flux, double sal, bool active_, double temp, double pres);
AquiferFlux() = default;
int id;
double flux;
double salt_concentration;
bool active;
int id {0};
double flux {0.};
double salt_concentration {0.};
bool active {false};
std::optional<double> temperature;
std::optional<double> datum_pressure;
// to work with ScheduleState::map_member
int name() const;
bool operator==(const AquiferFlux& other) const;
bool operator==(const SingleAquiferFlux& other) const;
template<class Serializer>
void serializeOp(Serializer& serializer)
@@ -61,7 +63,38 @@ namespace Opm {
serializer(this->datum_pressure);
}
static std::unordered_map<int, AquiferFlux> aqufluxFromKeywords(const std::vector<const DeckKeyword*>& keywords);
static SingleAquiferFlux serializationTestObject();
};
class AquiferFlux {
public:
using AquFluxs = std::unordered_map<int, SingleAquiferFlux>;
explicit AquiferFlux(const std::vector<const DeckKeyword*>& keywords);
AquiferFlux() = default;
void appendAqufluxSchedule(const std::unordered_set<int>& ids);
bool hasAquifer(int id) const;
bool operator==(const AquiferFlux& other) const;
size_t size() const;
std::unordered_map<int, SingleAquiferFlux>::const_iterator begin() const;
std::unordered_map<int, SingleAquiferFlux>::const_iterator end() const;
void loadFromRestart(const RestartIO::RstAquifer& rst);
template<class Serializer>
void serializeOp(Serializer& serializer) {
serializer(this->m_aquifers);
}
static AquiferFlux serializationTestObject();
private:
AquFluxs m_aquifers;
};
} // end of namespace Opm

View File

@@ -476,7 +476,7 @@ namespace Opm {
map_member<std::string, Group> groups;
map_member<std::string, Well> wells;
// constant flux aquifers
std::unordered_map<int, AquiferFlux> aqufluxs;
std::unordered_map<int, SingleAquiferFlux> aqufluxs;
std::unordered_map<std::string, double> target_wellpi;
std::optional<NextStep> next_tstep;

View File

@@ -34,13 +34,13 @@ AquiferConfig::AquiferConfig(const TableManager& tables,
const FieldPropsManager& field_props)
: aquifetp(tables, deck)
, aquiferct(tables, deck)
, aquiferflux(AquiferFlux::aqufluxFromKeywords(SOLUTIONSection(deck).getKeywordList("AQUFLUX")) )
, aquiferflux(SOLUTIONSection(deck).getKeywordList("AQUFLUX"))
, numerical_aquifers(deck, grid, field_props)
{}
AquiferConfig::AquiferConfig(const Aquifetp& fetp,
const AquiferCT& ct,
const AquFluxs& aqufluxs,
const AquiferFlux& aqufluxs,
const Aquancon& conn)
: aquifetp(fetp)
, aquiferct(ct)
@@ -65,8 +65,8 @@ void AquiferConfig::loadFromRestart(const RestartIO::RstAquifer& aquifers,
{
this->aquifetp.loadFromRestart(aquifers, tables);
this->aquiferct.loadFromRestart(aquifers, tables);
this->aquiferflux.loadFromRestart(aquifers);
this->aqconn.loadFromRestart(aquifers);
// TODO: loadFromrestart for AQUFLUX;
}
AquiferConfig AquiferConfig::serializationTestObject()
@@ -75,16 +75,15 @@ AquiferConfig AquiferConfig::serializationTestObject()
result.aquifetp = Aquifetp::serializationTestObject();
result.aquiferct = AquiferCT::serializationTestObject();
result.aqconn = Aquancon::serializationTestObject();
result.aquiferflux = AquiferFlux::serializationTestObject();
result.numerical_aquifers = NumericalAquifers::serializationTestObject();
// TODO: serializationTestObject for AQUFLUX
return result;
}
bool AquiferConfig::active() const {
return this->hasAnalyticalAquifer() ||
this->hasNumericalAquifer() ||
!this->aquiferflux.empty() ;
this->hasNumericalAquifer();
}
bool AquiferConfig::operator==(const AquiferConfig& other) const {
@@ -107,7 +106,7 @@ const Aquancon& AquiferConfig::connections() const {
return this->aqconn;
}
const AquiferConfig::AquFluxs& AquiferConfig::aquflux() const {
const AquiferFlux& AquiferConfig::aquflux() const {
return this->aquiferflux;
}
@@ -119,7 +118,7 @@ bool AquiferConfig::hasAquifer(const int aquID) const {
bool AquiferConfig::hasAnalyticalAquifer(const int aquID) const {
return aquifetp.hasAquifer(aquID) ||
aquiferct.hasAquifer(aquID) ||
aquiferflux.count(aquID) > 0;
aquiferflux.hasAquifer(aquID);
}
bool AquiferConfig::hasNumericalAquifer() const {
@@ -137,17 +136,11 @@ NumericalAquifers& AquiferConfig::mutableNumericalAquifers() const {
bool AquiferConfig::hasAnalyticalAquifer() const {
return (this->aquiferct.size() > std::size_t{0})
|| (this->aquifetp.size() > std::size_t{0})
|| !this->aquiferflux.empty();
|| (this->aquiferflux.size() > std::size_t{0});
}
void AquiferConfig::appendAqufluxSchedule(const std::unordered_set<int>& ids) {
for (const auto& id : ids) {
if (this->aquiferflux.find(id) == this->aquiferflux.end()) {
// we create an inactvie dummy aquflux aquifers,
// while essentially, we only need the list of the ids
this->aquiferflux.insert({id, AquiferFlux{id}});
}
}
this->aquiferflux.appendAqufluxSchedule(ids);
}
} // end of namespace Opm
@@ -165,8 +158,8 @@ std::vector<int> Opm::analyticAquiferIDs(const AquiferConfig& cfg)
for (const auto& aquifer : cfg.fetp())
aquiferIDs.push_back(aquifer.aquiferID);
for ([[maybe_unused]] const auto& [id, aqu] : cfg.aquflux())
aquiferIDs.push_back(id);
for (const auto& aquifer : cfg.aquflux())
aquiferIDs.push_back(aquifer.second.id);
std::sort(aquiferIDs.begin(), aquiferIDs.end());

View File

@@ -24,7 +24,7 @@
#include <opm/input/eclipse/Deck/DeckRecord.hpp>
namespace Opm {
AquiferFlux::AquiferFlux(const DeckRecord& record)
SingleAquiferFlux::SingleAquiferFlux(const DeckRecord& record)
: id (record.getItem<ParserKeywords::AQUFLUX::AQUIFER_ID>().get<int>(0))
, flux(record.getItem<ParserKeywords::AQUFLUX::FLUX>().getSIDouble(0))
, salt_concentration(record.getItem<ParserKeywords::AQUFLUX::SC_0>().getSIDouble(0))
@@ -39,13 +39,23 @@ namespace Opm {
}
}
AquiferFlux::AquiferFlux(const int aquifer_id)
SingleAquiferFlux::SingleAquiferFlux(const int aquifer_id)
: id (aquifer_id)
, active(false)
{
}
bool AquiferFlux::operator==(const AquiferFlux& other) const {
SingleAquiferFlux::SingleAquiferFlux(const int id_arg, const double flux_arg, const double sal,
const bool active_arg, double temp, double pres)
: id(id_arg)
, flux(flux_arg)
, salt_concentration(sal)
, active(active_arg)
, temperature(temp)
, datum_pressure(pres)
{}
bool SingleAquiferFlux::operator==(const SingleAquiferFlux& other) const {
return this->id == other.id &&
this->flux == other.flux &&
this->salt_concentration == other.salt_concentration &&
@@ -54,21 +64,58 @@ namespace Opm {
this->datum_pressure == other.datum_pressure;
}
int AquiferFlux::name() const
{
return this->id;
SingleAquiferFlux SingleAquiferFlux::serializationTestObject() {
SingleAquiferFlux result(1, 5., 3.0, true, 8.0, 10.0);
return result;
}
std::unordered_map<int, AquiferFlux>
AquiferFlux::aqufluxFromKeywords(const std::vector<const DeckKeyword*>& keywords)
{
std::unordered_map<int, AquiferFlux> aquifer_constant_flux;
for (const auto* keyword : keywords) {
for (const auto& record : *keyword) {
AquiferFlux aquifer(record);
aquifer_constant_flux.insert_or_assign(aquifer.id, aquifer);
void AquiferFlux::appendAqufluxSchedule(const std::unordered_set<int>& ids) {
for (const auto& id : ids) {
if (this->m_aquifers.count(id) == 0) {
// we create an inactvie dummy aquflux aquifers,
// while essentially, we only need the list of the ids
this->m_aquifers.insert({id, SingleAquiferFlux{id}});
}
}
return aquifer_constant_flux;
}
AquiferFlux::AquiferFlux(const std::vector<const DeckKeyword*>& keywords) {
for (const auto* keyword : keywords) {
for (const auto& record : *keyword) {
SingleAquiferFlux aquifer(record);
this->m_aquifers.insert_or_assign(aquifer.id, aquifer);
}
}
}
bool AquiferFlux::operator==(const AquiferFlux& other) const {
return this->m_aquifers == other.m_aquifers;
}
bool AquiferFlux::hasAquifer(const int id) const {
return this->m_aquifers.count(id) > 0;
}
size_t AquiferFlux::size() const {
return this->m_aquifers.size();
}
std::unordered_map<int, SingleAquiferFlux>::const_iterator AquiferFlux::begin() const {
return this->m_aquifers.begin();
}
std::unordered_map<int, SingleAquiferFlux>::const_iterator AquiferFlux::end() const {
return this->m_aquifers.end();
}
void AquiferFlux::loadFromRestart(const RestartIO::RstAquifer&) {
// TODO: adding the restart functionality
}
AquiferFlux AquiferFlux::serializationTestObject() {
AquiferFlux result;
auto single_aquifer = SingleAquiferFlux::serializationTestObject();
result.m_aquifers.insert({single_aquifer.id, single_aquifer});
return result;
}
} // end of namespace Opm

View File

@@ -137,7 +137,7 @@ namespace {
// auto& aqufluxs = this->snapshots.back().aqufluxs;
auto& aqufluxs = this->snapshots.back().aqufluxs;
for (const auto& record : handlerContext.keyword) {
AquiferFlux aquifer(record);
SingleAquiferFlux aquifer(record);
aqufluxs.insert({aquifer.id, aquifer});
}
}

View File

@@ -912,8 +912,6 @@ namespace {
int getMaximumAnalyticAquiferID(const Opm::AquiferConfig& cfg)
{
// TODO: this can be based on AQUCT and AQUFETP and AQUFLUX
// but there are pros and cons
const auto& aquifer_ids = analyticAquiferIDs(cfg);
return *max_element(std::begin(aquifer_ids), std::end(aquifer_ids));
}

View File

@@ -32,6 +32,7 @@
#include <opm/input/eclipse/EclipseState/Aquifer/Aquancon.hpp>
#include <opm/input/eclipse/EclipseState/Aquifer/AquiferCT.hpp>
#include <opm/input/eclipse/EclipseState/Aquifer/Aquifetp.hpp>
#include <opm/input/eclipse/EclipseState/Aquifer/AquiferFlux.hpp>
#include <opm/input/eclipse/EclipseState/Aquifer/AquiferConfig.hpp>
#include <opm/input/eclipse/EclipseState/EclipseState.hpp>
#include <opm/input/eclipse/EclipseState/Grid/EclipseGrid.hpp>
@@ -339,9 +340,9 @@ AQUTAB
return Opm::Aquifetp(properties);
}
Opm::AquiferConfig::AquFluxs createAquiferFluxs() {
Opm::AquiferFlux createAquiferFluxs() {
// TODO: just for compilation for now, will complete it
Opm::AquiferConfig::AquFluxs aquifers;
Opm::AquiferFlux aquifers;
return aquifers;
}