mirror of
https://github.com/OPM/opm-simulators.git
synced 2026-11-03 20:56:43 -06:00
Debugging code to dump guide rates
Added debugging code to dump all guide rates
This commit is contained in:
1 parent
827cda4f79
commit
006be80de0
6 files changed
+367
-24
No files matched your search
@@ -232,6 +232,7 @@ public:
|
||||
const SummaryState& summaryState() const { return summaryState_; }
|
||||
|
||||
const GuideRate& guideRate() const { return guideRate_; }
|
||||
GuideRate& guideRate() { return guideRate_; }
|
||||
|
||||
const std::map<std::string, double>& wellOpenTimes() const { return well_open_times_; }
|
||||
const std::map<std::string, double>& wellCloseTimes() const { return well_close_times_; }
|
||||
|
||||
@@ -388,9 +388,9 @@ getGuideRateInjectionGroupValues(const Group& group) const
|
||||
}
|
||||
|
||||
template<class Scalar>
|
||||
void BlackoilWellModelGuideRates<Scalar>::
|
||||
assignWellGuideRates(data::Wells& wsrpt,
|
||||
const int reportStepIdx) const
|
||||
std::unordered_map<std::string, data::GuideRateValue>
|
||||
BlackoilWellModelGuideRates<Scalar>::
|
||||
calculateWellGuideRates(const int reportStepIdx) const
|
||||
{
|
||||
auto all = std::unordered_map<std::string, data::GuideRateValue>{};
|
||||
auto retrieve = std::unordered_map<std::string, RetrieveWellGuideRate>{};
|
||||
@@ -470,7 +470,15 @@ assignWellGuideRates(data::Wells& wsrpt,
|
||||
// Upon completion, 'all' contains guide rate values for all wells
|
||||
// reachable from 'FIELD' at this time/report step.
|
||||
walker.traversePreOrder();
|
||||
return all;
|
||||
}
|
||||
|
||||
template<class Scalar>
|
||||
void BlackoilWellModelGuideRates<Scalar>::
|
||||
assignWellGuideRates(data::Wells& wsrpt,
|
||||
const int reportStepIdx) const
|
||||
{
|
||||
auto all = calculateWellGuideRates(reportStepIdx);
|
||||
for (const auto* well : wellModel_.genericWells()) {
|
||||
auto xwPos = wsrpt.find(well->name());
|
||||
if (xwPos == wsrpt.end()) { // No well results. Unexpected.
|
||||
|
||||
@@ -50,6 +50,10 @@ public:
|
||||
: wellModel_(wellModel)
|
||||
{}
|
||||
|
||||
//! \brief Calculate guide rate values for all wells.
|
||||
std::unordered_map<std::string, data::GuideRateValue>
|
||||
calculateWellGuideRates(const int reportStepIdx) const;
|
||||
|
||||
//! \brief Assign well guide rates.
|
||||
void assignWellGuideRates(data::Wells& wsrpt,
|
||||
const int reportStepIdx) const;
|
||||
|
||||
@@ -79,16 +79,11 @@ namespace Opm {
|
||||
phase_usage,
|
||||
simulator.gridView().comm())
|
||||
, simulator_(simulator)
|
||||
, guide_rate_handler_{simulator.vanguard().schedule(),
|
||||
// NOTE: The reference phase_usage passed to this constructor should be copied
|
||||
// as it will be destroyed by the caller. This is also what is done in
|
||||
// the parent class BlackoilWellModelGeneric and why we below use a reference
|
||||
// to that copy (this->phase_usage_) instead of the the constructor parameter
|
||||
// phase_usage
|
||||
this->phase_usage_,
|
||||
, guide_rate_handler_{
|
||||
*this,
|
||||
simulator.vanguard().schedule(),
|
||||
simulator.vanguard().summaryState(),
|
||||
simulator.vanguard().grid().comm(),
|
||||
this->guideRate_
|
||||
simulator.vanguard().grid().comm()
|
||||
}
|
||||
, gaslift_(this->terminal_output_, this->phase_usage_)
|
||||
{
|
||||
@@ -1295,7 +1290,6 @@ namespace Opm {
|
||||
this->guide_rate_handler_.updateGuideRates(
|
||||
reportStepIdx, simulationTime, this->wellState(), this->groupState()
|
||||
);
|
||||
|
||||
}
|
||||
// we need to re-iterate the network when the well group controls changed or gaslift/alq is changed or
|
||||
// the inner iterations are did not converge
|
||||
|
||||
@@ -17,11 +17,17 @@
|
||||
along with OPM. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#include <config.h>
|
||||
#include <opm/input/eclipse/EclipseState/Phase.hpp>
|
||||
#include <opm/output/data/GuideRateValue.hpp>
|
||||
#include <opm/simulators/utils/DeferredLoggingErrorHelpers.hpp>
|
||||
#include <opm/simulators/utils/ParallelCommunication.hpp>
|
||||
#include <opm/simulators/wells/GuideRateHandler.hpp>
|
||||
#include <opm/common/TimingMacros.hpp>
|
||||
|
||||
#include <utility>
|
||||
|
||||
#include <fmt/format.h>
|
||||
|
||||
namespace Opm {
|
||||
|
||||
// ---------------------------------------------
|
||||
@@ -29,18 +35,19 @@ namespace Opm {
|
||||
// ---------------------------------------------
|
||||
template <class Scalar>
|
||||
GuideRateHandler<Scalar>::GuideRateHandler(
|
||||
BlackoilWellModelGeneric<Scalar>& well_model,
|
||||
const Schedule& schedule,
|
||||
const PhaseUsage& phase_usage,
|
||||
const SummaryState& summary_state,
|
||||
const Parallel::Communication& comm,
|
||||
GuideRate& guide_rate
|
||||
const Parallel::Communication& comm
|
||||
) :
|
||||
schedule_{schedule}
|
||||
, phase_usage_{phase_usage}
|
||||
well_model_{well_model}
|
||||
, schedule_{schedule}
|
||||
, summary_state_{summary_state}
|
||||
, comm_{comm}
|
||||
, guide_rate_{guide_rate}
|
||||
{ }
|
||||
, phase_usage_{well_model_.phaseUsage()}
|
||||
, guide_rate_{well_model_.guideRate()}
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
// ----------------------------------------------------------
|
||||
@@ -56,6 +63,31 @@ deferredLogger()
|
||||
return *this->deferred_logger_;
|
||||
}
|
||||
|
||||
// This is an alternative to plotting the summary keywords:
|
||||
// - GOPGR (group oil production guide rate),
|
||||
// - WOPGR (well oil production guide rate),
|
||||
// - GWPGR (group water production guide rate),
|
||||
// - WWPGR (well water production guide rate),
|
||||
// - GGPGR (group gas production guide rate),
|
||||
// - WGPGR (well gas production guide rate),
|
||||
// - GGIGR (group gas injection guide rate),
|
||||
// - WGIGR (well gas injection guide rate),
|
||||
// - GWIGR (group water injection guide rate),
|
||||
// - WWIGR (well water injection guide rate),
|
||||
// - GVPGR (group reservoir volume production guide rate),
|
||||
// - WVPGR (well reservoir volume production guide rate),
|
||||
template <class Scalar>
|
||||
void
|
||||
GuideRateHandler<Scalar>::
|
||||
debugDumpGuideRates(const int report_step_idx, const double sim_time)
|
||||
{
|
||||
if (this->comm_.rank() == 0) {
|
||||
GuideRateDumper dumper{*this, report_step_idx, sim_time};
|
||||
dumper.dumpGuideRates();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#ifdef RESERVOIR_COUPLING_ENABLED
|
||||
template <class Scalar>
|
||||
void
|
||||
@@ -137,6 +169,266 @@ updateGuideRates(
|
||||
|
||||
}
|
||||
|
||||
// ------------------------------------------
|
||||
// Inner class GuideRateDumper constructor
|
||||
// ------------------------------------------
|
||||
|
||||
template <class Scalar>
|
||||
GuideRateHandler<Scalar>::GuideRateDumper::
|
||||
GuideRateDumper(
|
||||
GuideRateHandler<Scalar> &parent, const int report_step_idx, const double sim_time
|
||||
) : parent_{parent}
|
||||
, report_step_idx_{report_step_idx}
|
||||
, sim_time_{sim_time}
|
||||
, well_model_{parent.wellModel()}
|
||||
, schedule_{parent.schedule()}
|
||||
, comm_{parent.getComm()}
|
||||
{
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------
|
||||
// Public methods for inner class GuideRateDumper sorted alphabetically
|
||||
// ---------------------------------------------------------------------
|
||||
|
||||
template <class Scalar>
|
||||
void
|
||||
GuideRateHandler<Scalar>::GuideRateDumper::
|
||||
dumpGuideRates()
|
||||
{
|
||||
if (this->comm_.rank() == 0) {
|
||||
auto calcGR = BlackoilWellModelGuideRates{this->well_model_};
|
||||
this->well_guide_rates_ = calcGR.calculateWellGuideRates(this->report_step_idx_);
|
||||
this->group_guide_rates_ = calcGR.calculateAllGroupGuideRates(this->report_step_idx_);
|
||||
const auto& group = this->schedule_.getGroup("FIELD", this->report_step_idx_);
|
||||
printHeader_();
|
||||
int level = 0; // 0 is the root level
|
||||
this->dumpGuideRatesRecursive_(group, level);
|
||||
printTrailer_();
|
||||
}
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------
|
||||
// Private methods for GuideRateHandler sorted alphabetically
|
||||
// -----------------------------------------------------------
|
||||
|
||||
|
||||
template <class Scalar>
|
||||
void
|
||||
GuideRateHandler<Scalar>::GuideRateDumper::
|
||||
dumpGuideRatesRecursive_(const Group& group, int level)
|
||||
{
|
||||
if (group.name() != "FIELD") {
|
||||
this->printGroupGuideRates_(group, level);
|
||||
}
|
||||
for (const std::string& group_name : group.groups()) {
|
||||
const Group& group_tmp = this->schedule_.getGroup(group_name, this->report_step_idx_);
|
||||
this->dumpGuideRatesRecursive_(group_tmp, level+1);
|
||||
}
|
||||
for (const std::string& well_name : group.wells()) {
|
||||
const auto& well_tmp = this->schedule_.getWell(well_name, this->report_step_idx_);
|
||||
printWellGuideRates_(well_tmp, level+1);
|
||||
}
|
||||
}
|
||||
|
||||
template <class Scalar>
|
||||
void
|
||||
GuideRateHandler<Scalar>::GuideRateDumper::
|
||||
getGroupGuideRatesInjection_(
|
||||
const Group& group,
|
||||
const data::GroupGuideRates& group_guide_rate,
|
||||
std::vector<std::string>& msg_items
|
||||
) const
|
||||
{
|
||||
// NOTE: See comment in getGroupGuideRatesProduction_() for a discussion of the
|
||||
// different types of group guiderate enums.
|
||||
const auto& wm_guide_rate = this->well_model_.guideRate();
|
||||
const auto& name = group.name();
|
||||
using Value = data::GuideRateValue::Item;
|
||||
constexpr std::pair<Phase, Value> phase_value_pairs[] = {
|
||||
{Phase::OIL, Value::Oil},
|
||||
{Phase::GAS, Value::Gas},
|
||||
{Phase::WATER, Value::Water}
|
||||
};
|
||||
const auto& guide_rate_value = group_guide_rate.production;
|
||||
for (const auto& [phase, value] : phase_value_pairs) {
|
||||
if (wm_guide_rate.has(name, phase)) {
|
||||
if (guide_rate_value.has(value)) {
|
||||
msg_items.push_back(
|
||||
fmt::format(
|
||||
"{}(Group Inj, {}): {}",
|
||||
guide_rate_value.itemName(value),
|
||||
guide_rate_value.get(value)
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
template <class Scalar>
|
||||
void
|
||||
GuideRateHandler<Scalar>::GuideRateDumper::
|
||||
getGroupGuideRatesProduction_(
|
||||
const Group& group,
|
||||
const data::GroupGuideRates& group_guide_rate,
|
||||
std::vector<std::string>& msg_items
|
||||
) const
|
||||
{
|
||||
// NOTE: There are many different types of group guide rate phase target enums that are
|
||||
// used in different contexts:
|
||||
// - Group.hpp defines Group::GuideRateProdTarget and Group::GuideRateInjTarget
|
||||
// - Production: OIL, WAT, GAS, LIQ, RES, COMB, WGA, CVAL, INJV, POTN, FORM
|
||||
// - These are defined by item 9 of GCONPROD and used if item 10 of GCONPROD is not
|
||||
// set to FORM.
|
||||
// - Injection: RATE, VOID, NETV, RESV
|
||||
// - GuideRateModel.hpp defines GuideRateModel::Target
|
||||
// - OIL, LIQ, GAS, WAT, RES, COMB, NONE
|
||||
// - These are defined by item 2 of GUIDERAT.
|
||||
// - These are used if item 10 of GCONPROD is set to FORM, then the guide rate set in
|
||||
// item 9 of GCONPROD is ignored.
|
||||
// - Phase.hpp defines the Phase enum which is used by BlackoilWellModelGuideRates.cpp and
|
||||
// GuideRate.cpp
|
||||
// - OIL, GAS, WATER, SOLVENT, POLYMER, ENERGY, POLYMW, FOAM, BRINE
|
||||
// - Only OIL, GAS, WATER are used in the context of guide rates and only for
|
||||
// injection groups. And only GAS and WATER are checked for in
|
||||
// getGuideRateInjectionGroupValues() in BlackoilWellModelGuideRates.cpp.
|
||||
// - GuideRateValue.hpp defines GuideRateValue::Item which is used by
|
||||
// BlackoilWellModelGuideRates.cpp to assign guide rates. The values are:
|
||||
// - Oil, Gas, Water, ResV
|
||||
// - However, ResV is not implemented, see getGuideRateValues() in
|
||||
// BlackoilWellModelGuideRates.cpp. This, despite the summary keywords GVPGR and WVPGR
|
||||
// are using it, see Summary.cpp. TODO: Check if this is a bug.
|
||||
const auto& wm_guide_rate = this->well_model_.guideRate();
|
||||
const auto& name = group.name();
|
||||
if (wm_guide_rate.has(name)) { // Check if group has production guiderates
|
||||
constexpr data::GuideRateValue::Item value_types[] = {
|
||||
data::GuideRateValue::Item::Oil,
|
||||
data::GuideRateValue::Item::Gas,
|
||||
data::GuideRateValue::Item::Water,
|
||||
data::GuideRateValue::Item::ResV
|
||||
};
|
||||
const auto& guide_rate_value = group_guide_rate.production;
|
||||
for (const auto& value_type : value_types) {
|
||||
if (guide_rate_value.has(value_type)) {
|
||||
msg_items.push_back(
|
||||
fmt::format(
|
||||
"{}(Group Prod, {}): {}",
|
||||
name,
|
||||
guide_rate_value.itemName(value_type),
|
||||
guide_rate_value.get(value_type)
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
template <class Scalar>
|
||||
void
|
||||
GuideRateHandler<Scalar>::GuideRateDumper::
|
||||
printGroupGuideRates_(const Group& group, int level)
|
||||
{
|
||||
const auto& name = group.name();
|
||||
assert( level >= 1 );
|
||||
std::string indent(level - 1, ' ');
|
||||
auto gr_itr = this->group_guide_rates_.find(name);
|
||||
if (gr_itr == this->group_guide_rates_.end()) {
|
||||
this->deferredLogger().debug(
|
||||
fmt::format("{}{}: <NO GUIDERATE>", indent, name)
|
||||
);
|
||||
return;
|
||||
}
|
||||
const auto& group_guide_rate = gr_itr->second;
|
||||
std::vector<std::string> msg_items;
|
||||
getGroupGuideRatesProduction_(group, group_guide_rate, msg_items);
|
||||
getGroupGuideRatesInjection_(group, group_guide_rate, msg_items);
|
||||
if (msg_items.empty()) {
|
||||
this->deferredLogger().debug(
|
||||
fmt::format("{}{}(Group): <NO GUIDERATES FOUND>", indent, name)
|
||||
);
|
||||
return;
|
||||
}
|
||||
this->deferredLogger().debug(
|
||||
fmt::format("{}{}", indent, fmt::join(msg_items, ", "))
|
||||
);
|
||||
}
|
||||
|
||||
template <class Scalar>
|
||||
void
|
||||
GuideRateHandler<Scalar>::GuideRateDumper::
|
||||
printHeader_()
|
||||
{
|
||||
this->deferredLogger().debug(
|
||||
fmt::format(
|
||||
"\n---- GUIDE RATE REPORT: step {}, simtime {} ----",
|
||||
this->report_step_idx_,
|
||||
this->sim_time_
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
template <class Scalar>
|
||||
void
|
||||
GuideRateHandler<Scalar>::GuideRateDumper::
|
||||
printTrailer_()
|
||||
{
|
||||
this->deferredLogger().debug(
|
||||
fmt::format(
|
||||
"---- END GUIDE RATE REPORT: step {}, simtime {} ----\n",
|
||||
this->report_step_idx_,
|
||||
this->sim_time_
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
template <class Scalar>
|
||||
void
|
||||
GuideRateHandler<Scalar>::GuideRateDumper::
|
||||
printWellGuideRates_(const Well& well, int level)
|
||||
{
|
||||
const auto& name = well.name();
|
||||
assert( level >= 1 );
|
||||
std::string indent(level - 1, ' ');
|
||||
auto gr_itr = this->well_guide_rates_.find(name);
|
||||
if (gr_itr == this->well_guide_rates_.end()) {
|
||||
this->deferredLogger().debug(
|
||||
fmt::format("{}{}: <NO GUIDERATE>", indent, name)
|
||||
);
|
||||
return;
|
||||
}
|
||||
const auto& guide_rate_value = gr_itr->second;
|
||||
std::vector<std::string> msg_items;
|
||||
constexpr data::GuideRateValue::Item value_types[] = {
|
||||
data::GuideRateValue::Item::Oil,
|
||||
data::GuideRateValue::Item::Gas,
|
||||
data::GuideRateValue::Item::Water
|
||||
};
|
||||
const std::string well_type = well.isInjector() ? "Inj" : "Prod";
|
||||
for (const auto& value_type : value_types) {
|
||||
if (guide_rate_value.has(value_type)) {
|
||||
msg_items.push_back(
|
||||
fmt::format(
|
||||
"{}(Well {}, {}): {}",
|
||||
name,
|
||||
well_type,
|
||||
guide_rate_value.itemName(value_type),
|
||||
guide_rate_value.get(value_type)
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
if (msg_items.empty()) {
|
||||
this->deferredLogger().debug(
|
||||
fmt::format("{}{}(Well {}): <NO GUIDERATES FOUND>", indent, name, well_type)
|
||||
);
|
||||
return;
|
||||
}
|
||||
this->deferredLogger().debug(
|
||||
fmt::format("{}{}", indent, fmt::join(msg_items, ", "))
|
||||
);
|
||||
}
|
||||
|
||||
// ------------------------------------------
|
||||
// Inner class UpdateGuideRates constructor
|
||||
// ------------------------------------------
|
||||
|
||||
@@ -29,8 +29,12 @@
|
||||
#include <opm/simulators/flow/ReservoirCouplingSlave.hpp>
|
||||
#endif
|
||||
#include <opm/input/eclipse/Schedule/Group/GuideRate.hpp>
|
||||
#include <opm/output/data/Groups.hpp>
|
||||
#include <opm/output/data/GuideRateValue.hpp>
|
||||
#include <opm/simulators/utils/BlackoilPhases.hpp>
|
||||
#include <opm/simulators/utils/DeferredLogger.hpp>
|
||||
#include <opm/simulators/wells/BlackoilWellModelGeneric.hpp>
|
||||
#include <opm/simulators/wells/BlackoilWellModelGuideRates.hpp>
|
||||
#include <opm/simulators/wells/GroupState.hpp>
|
||||
#include <opm/simulators/wells/WellState.hpp>
|
||||
namespace Opm {
|
||||
@@ -40,6 +44,41 @@ class GuideRateHandler {
|
||||
public:
|
||||
using Potentials = ReservoirCoupling::Potentials;
|
||||
|
||||
class GuideRateDumper {
|
||||
public:
|
||||
GuideRateDumper(
|
||||
GuideRateHandler<Scalar> &parent, const int report_step_idx, const double sim_time
|
||||
);
|
||||
|
||||
DeferredLogger &deferredLogger() { return this->parent_.deferredLogger(); }
|
||||
void dumpGuideRates();
|
||||
private:
|
||||
void dumpGuideRatesRecursive_(const Group& group, int level);
|
||||
void getGroupGuideRatesInjection_(
|
||||
const Group& group,
|
||||
const data::GroupGuideRates& group_guide_rate,
|
||||
std::vector<std::string>& msg_items
|
||||
) const;
|
||||
void getGroupGuideRatesProduction_(
|
||||
const Group& group,
|
||||
const data::GroupGuideRates& group_guide_rate,
|
||||
std::vector<std::string>& msg_items
|
||||
) const;
|
||||
void printGroupGuideRates_(const Group& group, int level);
|
||||
void printHeader_();
|
||||
void printTrailer_();
|
||||
void printWellGuideRates_(const Well& well, int level);
|
||||
|
||||
GuideRateHandler<Scalar> &parent_;
|
||||
const int report_step_idx_;
|
||||
const double sim_time_;
|
||||
const BlackoilWellModelGeneric<Scalar>& well_model_;
|
||||
const Schedule& schedule_;
|
||||
const Parallel::Communication& comm_;
|
||||
std::unordered_map<std::string, data::GuideRateValue> well_guide_rates_;
|
||||
std::unordered_map<std::string, data::GroupGuideRates> group_guide_rates_;
|
||||
};
|
||||
|
||||
class UpdateGuideRates {
|
||||
public:
|
||||
UpdateGuideRates(
|
||||
@@ -87,11 +126,10 @@ public:
|
||||
};
|
||||
|
||||
GuideRateHandler(
|
||||
BlackoilWellModelGeneric<Scalar>& well_model,
|
||||
const Schedule& schedule,
|
||||
const PhaseUsage& phase_usage,
|
||||
const SummaryState& summary_state,
|
||||
const Parallel::Communication& comm,
|
||||
GuideRate& guide_rate
|
||||
const Parallel::Communication& comm
|
||||
);
|
||||
|
||||
#ifdef RESERVOIR_COUPLING_ENABLED
|
||||
@@ -113,18 +151,24 @@ public:
|
||||
}
|
||||
#endif
|
||||
DeferredLogger& deferredLogger();
|
||||
void debugDumpGuideRates(const int report_step_idx, const double sim_time);
|
||||
const Parallel::Communication& getComm() const { return comm_; }
|
||||
void setLogger(DeferredLogger *deferred_logger);
|
||||
const Schedule& schedule() const { return schedule_; }
|
||||
void updateGuideRates(
|
||||
const int report_step_idx,
|
||||
const double sim_time,
|
||||
WellState<Scalar> &well_state,
|
||||
GroupState<Scalar> &group_state
|
||||
);
|
||||
const BlackoilWellModelGeneric<Scalar>& wellModel() const { return well_model_; }
|
||||
private:
|
||||
void debugDumpGuideRatesRecursive_(const Group& group) const;
|
||||
BlackoilWellModelGeneric<Scalar>& well_model_;
|
||||
const Schedule& schedule_;
|
||||
const PhaseUsage& phase_usage_;
|
||||
const SummaryState& summary_state_;
|
||||
const Parallel::Communication& comm_;
|
||||
const PhaseUsage& phase_usage_;
|
||||
GuideRate& guide_rate_;
|
||||
DeferredLogger *deferred_logger_ = nullptr;
|
||||
#ifdef RESERVOIR_COUPLING_ENABLED
|
||||
|
||||
Reference in new issue
Block a user