Files
opm-common/opm/parser/eclipse/EclipseState/Schedule/RFTConfig.hpp
Bård Skaflestad 8f182db27a Rework RFT Config to Handle More Cases
Generally, this commit captures more of the surrounding context of
calls to the updateRFT() and updatePLT() member functions.  We need
this additional context in order to handle the conflicting semantics
of output requests WRFT and WRFTPLT:FOPN.  The former generates RFT
output when the well opens if this event does not happen earlier in
the simulation schedule than the output request.  Otherwise no RFT
data is emitted.  The latter outputs RFT data at request time if
well opens no later than the request; otherwise at well-open time.

To this end, switch the well_open_rft_name data member from an
unordered_set of well names into an unordered_map from well names to
RFT output request times.  With this additional information we can
use well_open_rft_time to infer the appropriate response to whether
or not to activate RFT output at well open time.  Moreover, we now
guarantee that no RFT output is ever activated before the first RFT
output request.

Switching the type of the well_open_rft_name data member also begets
an API update to the serialization related RFTConfig constructor and
to the return type of RFTConfig::wellOpenRftName().

We furthermore switch to caching the first RFT output event in a new
scalar data member, first_rft_event.  This caching, coupled with the
additional calling context mentioned earlier, means we are now able
to report a high-fidelity, constant time answer to the

    RFTConfig::firstRFTOutput()

request.  This, in turn, is very useful for the RFT output code.
Finally, we also add a couple of new, private member functions to
simplify updating first_rft_event depending on context.

As part of this update, member function

    RFTConfig::setWellOpenRFT(report_step)

will now use the minimum of all 'report_step' values to support the
WRFT keyword being specified more than once.

Finally, add a set of unit tests to exercise the various RFT output
request combinations.

While here, also switch to using unordered_map::find() and emplace()
where possible to limit repeated look-up of the same keys.
2020-01-14 15:58:34 +01:00

124 lines
4.2 KiB
C++

/*
Copyright 2019 Equinor 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 RFT_CONFIG_HPP
#define RFT_CONFIG_HPP
#include <cstddef>
#include <string>
#include <unordered_map>
#include <utility>
#include <opm/parser/eclipse/EclipseState/Schedule/Well/Connection.hpp>
#include <opm/parser/eclipse/EclipseState/Schedule/DynamicState.hpp>
#include <opm/parser/eclipse/EclipseState/Schedule/TimeMap.hpp>
namespace Opm {
class RFTConfig {
public:
enum class RFT {
YES = 1,
REPT = 2,
TIMESTEP = 3,
FOPN = 4,
NO = 5
};
static std::string RFT2String(RFT enumValue);
static RFT RFTFromString(const std::string &stringValue);
enum class PLT {
YES = 1,
REPT = 2,
TIMESTEP = 3,
NO = 4
};
static std::string PLT2String(PLT enumValue);
static PLT PLTFromString( const std::string& stringValue);
using RFTMap = std::unordered_map<std::string,
DynamicState<std::pair<RFT, std::size_t>>>;
using PLTMap = std::unordered_map<std::string,
DynamicState<std::pair<PLT, std::size_t>>>;
using WellOpenTimeMap = std::unordered_map<std::string, std::size_t>;
RFTConfig();
RFTConfig(const TimeMap& tm,
const std::size_t first_rft,
const std::pair<bool, std::size_t>& rftTime,
const WellOpenTimeMap& rftName,
const WellOpenTimeMap& wellOpen,
const RFTMap& rconfig,
const PLTMap& pconfig);
explicit RFTConfig(const TimeMap& time_map);
bool rft(const std::string& well, std::size_t report_step) const;
bool plt(const std::string& well, std::size_t report_step) const;
bool getWellOpenRFT(const std::string& well_name, std::size_t report_step) const;
void setWellOpenRFT(std::size_t report_step);
void setWellOpenRFT(const std::string& well_name);
bool active(std::size_t report_step) const;
std::size_t firstRFTOutput() const { return this->first_rft_event; }
void updateRFT(const std::string& well, std::size_t report_step, RFT value);
void updatePLT(const std::string& well, std::size_t report_step, PLT value);
void addWellOpen(const std::string& well, std::size_t report_step);
const TimeMap& timeMap() const;
const std::pair<bool, std::size_t>& wellOpenRftTime() const;
const WellOpenTimeMap& wellOpenRftName() const;
const WellOpenTimeMap& wellOpen() const;
const RFTMap& rftConfig() const;
const PLTMap& pltConfig() const;
bool operator==(const RFTConfig& data) const;
private:
template <typename Value>
using ConfigMap = std::unordered_map<
std::string, DynamicState<std::pair<Value, std::size_t>>
>;
TimeMap tm;
std::size_t first_rft_event;
std::pair<bool, std::size_t> well_open_rft_time;
WellOpenTimeMap well_open_rft_name;
WellOpenTimeMap well_open;
RFTMap rft_config;
PLTMap plt_config;
bool outputRftAtWellopen(WellOpenTimeMap::const_iterator well, const std::size_t report_step) const;
std::size_t firstWellopenStepNotBefore(const std::size_t report_step) const;
void updateFirstIfNotShut(const std::string& well_name, const std::size_t report_step);
void updateFirst(const std::size_t report_step);
void setWellOpenRFT(const std::string& well_name, const std::size_t report_step);
template <typename Value>
void updateConfig(const std::string& well_name,
const std::size_t report_step,
const Value value,
ConfigMap<Value>& cfgmap);
};
}
#endif