Loading...
Searching...
No Matches
WellTestState.hpp
/*
Copyright 2018 Statoil ASA.
This file is part of the Open Porous Media project (OPM).
OPM is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
OPM is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with OPM. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef WELLTEST_STATE_H
#define WELLTEST_STATE_H
#include <opm/input/eclipse/Schedule/Well/WellTestConfig.hpp>
#include <opm/io/eclipse/rst/state.hpp>
#include <cstddef>
#include <ctime>
#include <optional>
#include <string>
#include <unordered_map>
#include <utility>
#include <vector>
namespace {
template<class BufferType, class M>
void pack_map(BufferType& buffer, const M& m) {
buffer.write(m.size());
for (const auto& [k,v] : m) {
buffer.write(k);
v.pack(buffer);
}
}
template<class BufferType, class M>
void unpack_map(BufferType& buffer, M& m) {
typename M::size_type size;
buffer.read(size);
for (std::size_t i = 0; i < size; i++) {
typename M::key_type k;
typename M::mapped_type v;
buffer.read(k);
v.unpack(buffer);
m.emplace(std::move(k), std::move(v));
}
}
}
namespace Opm {
class WellTestConfig;
namespace WTest { enum class Reason; }
class WellTestState {
public:
/*
This class implements a small mutable state object which keeps track of
which wells have been automatically closed by the simulator through the
WTEST mechanism.
The default behavior of the container is to manage *closed* wells, but
since the counter mechanism for the maximum number of opening attempts
should maintain the same counter through open/close events we need to
manage the well object also after they have been opened up again.
*/
struct RestartWell {
std::string name;
double test_interval;
int num_test;
double startup_time;
int config_reasons;
int close_reason;
RestartWell(const std::string& wname, double ti, int num, double st, int r1, int r2)
: name(wname)
, test_interval(ti)
, num_test(num)
, startup_time(st)
, config_reasons(r1)
, close_reason(r2)
{};
};
struct WTestWell {
std::string name{};
WTest::Reason reason{WTest::Reason::NONE};
double last_test{};
int num_attempt{0};
bool closed{true};
std::optional<int> wtest_report_step{};
WTestWell() = default;
WTestWell(const std::string& wname, WTest::Reason reason_, double last_test);
int int_reason() const;
static WTest::Reason inverse_ecl_reason(int ecl_reason);
bool operator==(const WTestWell& other) const {
return this->name == other.name &&
this->reason == other.reason &&
this->last_test == other.last_test &&
this->num_attempt == other.num_attempt &&
this->closed == other.closed &&
this->wtest_report_step == other.wtest_report_step;
}
static WTestWell serializationTestObject();
template<class Serializer>
void serializeOp(Serializer& serializer)
{
serializer(this->name);
serializer(this->reason);
serializer(this->last_test);
serializer(this->num_attempt);
serializer(this->closed);
serializer(this->wtest_report_step);
}
template<class BufferType>
void pack(BufferType& buffer) const {
buffer.write(this->name);
buffer.write(this->reason);
buffer.write(this->last_test);
buffer.write(this->num_attempt);
buffer.write(this->closed);
buffer.write(this->wtest_report_step);
}
template<class BufferType>
void unpack(BufferType& buffer) {
buffer.read(this->name);
buffer.read(this->reason);
buffer.read(this->last_test);
buffer.read(this->num_attempt);
buffer.read(this->closed);
buffer.read(this->wtest_report_step);
}
};
struct ClosedCompletion {
std::string wellName{};
int complnum{};
double last_test{};
int num_attempt{};
bool operator==(const ClosedCompletion& other) const {
return this->wellName == other.wellName &&
this->complnum == other.complnum &&
this->last_test == other.last_test &&
this->num_attempt == other.num_attempt;
}
static ClosedCompletion serializationTestObject();
template<class Serializer>
void serializeOp(Serializer& serializer)
{
serializer(this->wellName);
serializer(this->complnum);
serializer(this->last_test);
serializer(this->num_attempt);
}
template<class BufferType>
void pack(BufferType& buffer) const {
buffer.write(this->wellName);
buffer.write(this->complnum);
buffer.write(this->last_test);
buffer.write(this->num_attempt);
}
template<class BufferType>
void unpack(BufferType& buffer) {
buffer.read(this->wellName);
buffer.read(this->complnum);
buffer.read(this->last_test);
buffer.read(this->num_attempt);
}
};
WellTestState() = default;
WellTestState(std::time_t start_time, const RestartIO::RstState& rst_state);
std::vector<std::string> test_wells(const WellTestConfig& config, double sim_time);
void filter_wells(const std::vector<std::string>& existing_wells);
/*
The purpose of this container is to manage explicitly *closed wells*,
since the class has no relation to the set of of wells defined in the
Schedule section the concept of open wells and totally unknown wells is
slightly murky:
well_is_closed("UNKOWN_WELL") -> false
This implies that we have not explicitly closed a well with name
'UNKNOWN_WELL', but since we do not know whether the well is at all
defined it does not make sense to extrapolate to:
well_is_open("UNKNOWN_WELL") -> true.
That is the reason we do not have any xxx_is_open() predicates.
*/
void close_well(const std::string& well_name, WTest::Reason reason, double sim_time);
bool well_is_closed(const std::string& well_name) const;
void open_well(const std::string& well_name);
std::size_t num_closed_wells() const;
double lastTestTime(const std::string& well_name) const;
void close_completion(const std::string& well_name, int complnum, double sim_time);
void open_completion(const std::string& well_name, int complnum);
void open_completions(const std::string& well_name);
bool completion_is_closed(const std::string& well_name, const int complnum) const;
std::size_t num_closed_completions() const;
void clear();
template<class BufferType>
void pack(BufferType& buffer) const {
pack_map(buffer, this->wells);
buffer.write(this->completions.size());
for (const auto& [well, cmap] : this->completions) {
buffer.write(well);
pack_map(buffer, cmap);
}
}
template<class BufferType>
void unpack(BufferType& buffer) {
unpack_map(buffer, this->wells);
std::size_t size;
buffer.read(size);
for (std::size_t i = 0; i < size; i++) {
std::string well;
std::unordered_map<int, ClosedCompletion> cmap;
buffer.read(well);
unpack_map(buffer, cmap);
this->completions.emplace(std::move(well), std::move(cmap));
}
}
template<class Serializer>
void serializeOp(Serializer& serializer)
{
serializer(this->wells);
serializer(this->completions);
}
static WellTestState serializationTestObject();
bool operator==(const WellTestState& other) const;
std::optional<WellTestState::RestartWell> restart_well(const Opm::WellTestConfig& config, const std::string& wname) const;
private:
std::unordered_map<std::string, WTestWell> wells;
std::unordered_map<std::string, std::unordered_map<int, ClosedCompletion>> completions;
std::vector<std::pair<std::string, int>> updateCompletion(const WellTestConfig& config, double sim_time);
};
}
#endif
Opm::Serializer
Class for (de-)serializing.
Definition Serializer.hpp:94
Opm::WellTestConfig
Definition WellTestConfig.hpp:67
Opm
This class implements a small container which holds the transmissibility mulitpliers for all the face...
Definition Exceptions.hpp:30
Opm::RestartIO::RstState
Definition state.hpp:57
Opm::WellTestState::ClosedCompletion
Definition WellTestState.hpp:155