mirror of
https://github.com/OPM/opm-simulators.git
synced 2025-02-25 18:55:30 -06:00
Code improvment for the group control switching
Pass the controls as enums not strings Avoid pair as key in map
This commit is contained in:
parent
738eb761c2
commit
095c0457bc
@ -562,8 +562,8 @@ bool BlackoilWellModelConstraints<Scalar>::
|
|||||||
updateGroupIndividualControl(const Group& group,
|
updateGroupIndividualControl(const Group& group,
|
||||||
const int reportStepIdx,
|
const int reportStepIdx,
|
||||||
const int max_number_of_group_switch,
|
const int max_number_of_group_switch,
|
||||||
std::map<std::pair<std::string,Phase>,std::vector<std::string>>& switched_inj,
|
std::map<std::string, std::array<std::vector<Group::InjectionCMode>, 3>>& switched_inj,
|
||||||
std::map<std::string, std::vector<std::string>>& switched_prod,
|
std::map<std::string, std::vector<Group::ProductionCMode>>& switched_prod,
|
||||||
std::map<std::string, std::pair<std::string, std::string>>& closed_offending_wells,
|
std::map<std::string, std::pair<std::string, std::string>>& closed_offending_wells,
|
||||||
GroupState<Scalar>& group_state,
|
GroupState<Scalar>& group_state,
|
||||||
WellState<Scalar>& well_state,
|
WellState<Scalar>& well_state,
|
||||||
@ -577,31 +577,32 @@ updateGroupIndividualControl(const Group& group,
|
|||||||
if (!group.hasInjectionControl(phase)) {
|
if (!group.hasInjectionControl(phase)) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool group_is_oscillating = false;
|
bool group_is_oscillating = false;
|
||||||
if (switched_inj.count({group.name(), phase}) > 0) {
|
if (auto groupPos = switched_inj.find(group.name()); groupPos != switched_inj.end()) {
|
||||||
for (const auto& key : switched_inj[{group.name(), phase}]) {
|
auto& ctrls = groupPos->second[static_cast<std::underlying_type_t<Phase>>(phase)];
|
||||||
if (std::count(switched_inj[{group.name(), phase}].begin(), switched_inj[{group.name(), phase}].end(), key) >= max_number_of_group_switch) {
|
for (const auto& ctrl : ctrls) {
|
||||||
const size_t sz = switched_inj[{group.name(), phase}].size();
|
if (std::count(ctrls.begin(), ctrls.end(), ctrl) < max_number_of_group_switch) {
|
||||||
// only output if the two last keys are not the same.
|
continue;
|
||||||
if (key != switched_inj[{group.name(), phase}][sz-2]) {
|
|
||||||
if (wellModel_.comm().rank() == 0) {
|
|
||||||
std::ostringstream os;
|
|
||||||
os << phase;
|
|
||||||
const std::string msg =
|
|
||||||
fmt::format("Group control for {} injector group {} is oscillating. Group control kept at {}.",
|
|
||||||
std::move(os).str(),
|
|
||||||
group.name(),
|
|
||||||
key);
|
|
||||||
deferred_logger.info(msg);
|
|
||||||
}
|
|
||||||
switched_inj[{group.name(), phase}].push_back(key);
|
|
||||||
}
|
|
||||||
group_is_oscillating = true;
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (ctrls.back() != *(ctrls.end() - 2)) {
|
||||||
|
if (wellModel_.comm().rank() == 0 ) {
|
||||||
|
std::ostringstream os;
|
||||||
|
os << phase;
|
||||||
|
const std::string msg =
|
||||||
|
fmt::format("Group control for {} injector group {} is oscillating. Group control kept at {}.",
|
||||||
|
std::move(os).str(),
|
||||||
|
group.name(),
|
||||||
|
Group::InjectionCMode2String(ctrl));
|
||||||
|
deferred_logger.info(msg);
|
||||||
|
}
|
||||||
|
ctrls.push_back(ctrl);
|
||||||
|
}
|
||||||
|
group_is_oscillating = true;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (group_is_oscillating) {
|
if (group_is_oscillating) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@ -611,8 +612,8 @@ updateGroupIndividualControl(const Group& group,
|
|||||||
phase);
|
phase);
|
||||||
if (changed_this.first != Group::InjectionCMode::NONE)
|
if (changed_this.first != Group::InjectionCMode::NONE)
|
||||||
{
|
{
|
||||||
switched_inj[{group.name(), phase}].push_back(
|
switched_inj[group.name()][static_cast<std::underlying_type_t<Phase>>(phase)].push_back(
|
||||||
Group::InjectionCMode2String(changed_this.first));
|
changed_this.first);
|
||||||
|
|
||||||
this->actionOnBrokenConstraints(group, changed_this.first, phase,
|
this->actionOnBrokenConstraints(group, changed_this.first, phase,
|
||||||
group_state, deferred_logger);
|
group_state, deferred_logger);
|
||||||
@ -629,23 +630,24 @@ updateGroupIndividualControl(const Group& group,
|
|||||||
}
|
}
|
||||||
if (group.isProductionGroup()) {
|
if (group.isProductionGroup()) {
|
||||||
|
|
||||||
if (switched_prod.count(group.name()) > 0) {
|
if (auto groupPos = switched_prod.find(group.name()); groupPos != switched_prod.end()) {
|
||||||
for (const auto& key : switched_prod[group.name()]) {
|
auto& ctrls = groupPos->second;
|
||||||
if (std::count(switched_prod[group.name()].begin(), switched_prod[group.name()].end(), key) >= max_number_of_group_switch) {
|
for (const auto& ctrl : ctrls) {
|
||||||
const size_t sz = switched_prod[group.name()].size();
|
if (std::count(ctrls.begin(), ctrls.end(), ctrl) < max_number_of_group_switch) {
|
||||||
// only output on rank 0 and if the two last keys are not the same.
|
continue;
|
||||||
if (key != switched_prod[group.name()][sz-2]) {
|
|
||||||
if (wellModel_.comm().rank() == 0) {
|
|
||||||
const std::string msg =
|
|
||||||
fmt::format("Group control for production group {} is oscillating. Group control kept at {}.",
|
|
||||||
group.name(),
|
|
||||||
key);
|
|
||||||
deferred_logger.info(msg);
|
|
||||||
}
|
|
||||||
switched_prod[group.name()].push_back(key);
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (ctrls.back() != *(ctrls.end() - 2)) {
|
||||||
|
if (wellModel_.comm().rank() == 0) {
|
||||||
|
const std::string msg =
|
||||||
|
fmt::format("Group control for production group {} is oscillating. Group control kept at {}.",
|
||||||
|
group.name(),
|
||||||
|
Group::ProductionCMode2String(ctrl));
|
||||||
|
deferred_logger.info(msg);
|
||||||
|
}
|
||||||
|
ctrls.push_back(ctrl);
|
||||||
|
}
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -664,8 +666,7 @@ updateGroupIndividualControl(const Group& group,
|
|||||||
group_state, deferred_logger);
|
group_state, deferred_logger);
|
||||||
|
|
||||||
if(changed) {
|
if(changed) {
|
||||||
switched_prod[group.name()].push_back(
|
switched_prod[group.name()].push_back(changed_this.first);
|
||||||
Group::ProductionCMode2String(changed_this.first));
|
|
||||||
WellGroupHelpers<Scalar>::updateWellRatesFromGroupTargetScale(changed_this.second,
|
WellGroupHelpers<Scalar>::updateWellRatesFromGroupTargetScale(changed_this.second,
|
||||||
group,
|
group,
|
||||||
wellModel_.schedule(),
|
wellModel_.schedule(),
|
||||||
|
@ -74,8 +74,8 @@ public:
|
|||||||
bool updateGroupIndividualControl(const Group& group,
|
bool updateGroupIndividualControl(const Group& group,
|
||||||
const int reportStepIdx,
|
const int reportStepIdx,
|
||||||
const int max_number_of_group_switch,
|
const int max_number_of_group_switch,
|
||||||
std::map<std::pair<std::string,Phase>,std::vector<std::string>>& switched_inj,
|
std::map<std::string, std::array<std::vector<Group::InjectionCMode>, 3>>& switched_inj,
|
||||||
std::map<std::string, std::vector<std::string>>& switched_prod,
|
std::map<std::string, std::vector<Group::ProductionCMode>>& switched_prod,
|
||||||
std::map<std::string, std::pair<std::string, std::string>>& closed_offending_wells,
|
std::map<std::string, std::pair<std::string, std::string>>& closed_offending_wells,
|
||||||
GroupState<Scalar>& group_state,
|
GroupState<Scalar>& group_state,
|
||||||
WellState<Scalar>& well_state,
|
WellState<Scalar>& well_state,
|
||||||
|
@ -628,29 +628,31 @@ checkGroupHigherConstraints(const Group& group,
|
|||||||
const Phase all[] = { Phase::WATER, Phase::OIL, Phase::GAS };
|
const Phase all[] = { Phase::WATER, Phase::OIL, Phase::GAS };
|
||||||
for (Phase phase : all) {
|
for (Phase phase : all) {
|
||||||
bool group_is_oscillating = false;
|
bool group_is_oscillating = false;
|
||||||
if (switched_inj_groups_.count({group.name(), phase}) > 0) {
|
if (auto groupPos = switched_inj_groups_.find(group.name()); groupPos != switched_inj_groups_.end()) {
|
||||||
for (const auto& key : switched_inj_groups_[{group.name(), phase}]) {
|
auto& ctrls = groupPos->second[static_cast<std::underlying_type_t<Phase>>(phase)];
|
||||||
if (std::count(switched_inj_groups_[{group.name(), phase}].begin(), switched_inj_groups_[{group.name(), phase}].end(), key) >= max_number_of_group_switch) {
|
for (const auto& ctrl : ctrls) {
|
||||||
const size_t sz = switched_inj_groups_[{group.name(), phase}].size();
|
if (std::count(ctrls.begin(), ctrls.end(), ctrl) < max_number_of_group_switch) {
|
||||||
// only output if the two last keys are not the same.
|
continue;
|
||||||
if (key != switched_inj_groups_[{group.name(), phase}][sz-2]) {
|
|
||||||
if (comm_.rank() == 0 ) {
|
|
||||||
std::ostringstream os;
|
|
||||||
os << phase;
|
|
||||||
const std::string msg =
|
|
||||||
fmt::format("Group control for {} injector group {} is oscillating. Group control kept at {}.",
|
|
||||||
std::move(os).str(),
|
|
||||||
group.name(),
|
|
||||||
key);
|
|
||||||
deferred_logger.info(msg);
|
|
||||||
}
|
|
||||||
switched_inj_groups_[{group.name(), phase}].push_back(key);
|
|
||||||
}
|
|
||||||
group_is_oscillating = true;
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (ctrls.back() != *(ctrls.end() - 2)) {
|
||||||
|
if (comm_.rank() == 0 ) {
|
||||||
|
std::ostringstream os;
|
||||||
|
os << phase;
|
||||||
|
const std::string msg =
|
||||||
|
fmt::format("Group control for {} injector group {} is oscillating. Group control kept at {}.",
|
||||||
|
std::move(os).str(),
|
||||||
|
group.name(),
|
||||||
|
Group::InjectionCMode2String(ctrl));
|
||||||
|
deferred_logger.info(msg);
|
||||||
|
}
|
||||||
|
ctrls.push_back(ctrl);
|
||||||
|
}
|
||||||
|
group_is_oscillating = true;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (group_is_oscillating) {
|
if (group_is_oscillating) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@ -676,7 +678,7 @@ checkGroupHigherConstraints(const Group& group,
|
|||||||
resv_coeff_inj,
|
resv_coeff_inj,
|
||||||
deferred_logger);
|
deferred_logger);
|
||||||
if (is_changed) {
|
if (is_changed) {
|
||||||
switched_inj_groups_[{group.name(), phase}].push_back(Group::InjectionCMode2String(Group::InjectionCMode::FLD));
|
switched_inj_groups_[group.name()][static_cast<std::underlying_type_t<Phase>>(phase)].push_back(Group::InjectionCMode::FLD);
|
||||||
BlackoilWellModelConstraints(*this).
|
BlackoilWellModelConstraints(*this).
|
||||||
actionOnBrokenConstraints(group, Group::InjectionCMode::FLD,
|
actionOnBrokenConstraints(group, Group::InjectionCMode::FLD,
|
||||||
phase, this->groupState(),
|
phase, this->groupState(),
|
||||||
@ -700,23 +702,24 @@ checkGroupHigherConstraints(const Group& group,
|
|||||||
// So when checking constraints, current groups rate must also be subtracted it's reduction rate
|
// So when checking constraints, current groups rate must also be subtracted it's reduction rate
|
||||||
const std::vector<Scalar> reduction_rates = this->groupState().production_reduction_rates(group.name());
|
const std::vector<Scalar> reduction_rates = this->groupState().production_reduction_rates(group.name());
|
||||||
|
|
||||||
if (switched_prod_groups_.count(group.name()) > 0) {
|
if (auto groupPos = switched_prod_groups_.find(group.name()); groupPos != switched_prod_groups_.end()) {
|
||||||
for (const auto& key : switched_prod_groups_[group.name()]) {
|
auto& ctrls = groupPos->second;
|
||||||
if (std::count(switched_prod_groups_[group.name()].begin(), switched_prod_groups_[group.name()].end(), key) >= max_number_of_group_switch) {
|
for (const auto& ctrl : ctrls) {
|
||||||
const size_t sz = switched_prod_groups_[group.name()].size();
|
if (std::count(ctrls.begin(), ctrls.end(), ctrl) < max_number_of_group_switch) {
|
||||||
// only output on rank 0 and if the two last keys are not the same.
|
continue;
|
||||||
if (key != switched_prod_groups_[group.name()][sz-2]) {
|
|
||||||
if (comm_.rank() == 0) {
|
|
||||||
const std::string msg =
|
|
||||||
fmt::format("Group control for production group {} is oscillating. Group control kept at {}.",
|
|
||||||
group.name(),
|
|
||||||
key);
|
|
||||||
deferred_logger.info(msg);
|
|
||||||
}
|
|
||||||
switched_prod_groups_[group.name()].push_back(key);
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (ctrls.back() != *(ctrls.end() - 2)) {
|
||||||
|
if (comm_.rank() == 0) {
|
||||||
|
const std::string msg =
|
||||||
|
fmt::format("Group control for production group {} is oscillating. Group control kept at {}.",
|
||||||
|
group.name(),
|
||||||
|
Group::ProductionCMode2String(ctrl));
|
||||||
|
deferred_logger.info(msg);
|
||||||
|
}
|
||||||
|
ctrls.push_back(ctrl);
|
||||||
|
}
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for (int phasePos = 0; phasePos < phase_usage_.num_phases; ++phasePos) {
|
for (int phasePos = 0; phasePos < phase_usage_.num_phases; ++phasePos) {
|
||||||
@ -762,7 +765,7 @@ checkGroupHigherConstraints(const Group& group,
|
|||||||
deferred_logger);
|
deferred_logger);
|
||||||
|
|
||||||
if (changed) {
|
if (changed) {
|
||||||
switched_prod_groups_[group.name()].push_back(Group::ProductionCMode2String(Group::ProductionCMode::FLD));
|
switched_prod_groups_[group.name()].push_back(Group::ProductionCMode::FLD);
|
||||||
WellGroupHelpers<Scalar>::updateWellRatesFromGroupTargetScale(scaling_factor,
|
WellGroupHelpers<Scalar>::updateWellRatesFromGroupTargetScale(scaling_factor,
|
||||||
group,
|
group,
|
||||||
schedule(),
|
schedule(),
|
||||||
|
@ -599,8 +599,8 @@ protected:
|
|||||||
bool wellStructureChangedDynamically_{false};
|
bool wellStructureChangedDynamically_{false};
|
||||||
|
|
||||||
// Store maps of group name and new group controls for output
|
// Store maps of group name and new group controls for output
|
||||||
std::map<std::string, std::vector<std::string>> switched_prod_groups_;
|
std::map<std::string, std::vector<Group::ProductionCMode>> switched_prod_groups_;
|
||||||
std::map<std::pair<std::string, Phase>, std::vector<std::string>> switched_inj_groups_;
|
std::map<std::string, std::array<std::vector<Group::InjectionCMode>, 3>> switched_inj_groups_;
|
||||||
// Store map of group name and close offending well for output
|
// Store map of group name and close offending well for output
|
||||||
std::map<std::string, std::pair<std::string, std::string>> closed_offending_wells_;
|
std::map<std::string, std::pair<std::string, std::string>> closed_offending_wells_;
|
||||||
|
|
||||||
|
@ -749,29 +749,42 @@ namespace Opm {
|
|||||||
// report group switching
|
// report group switching
|
||||||
if (this->terminal_output_) {
|
if (this->terminal_output_) {
|
||||||
|
|
||||||
for (const auto& [name, to] : this->switched_prod_groups_) {
|
for (const auto& [name, ctrls] : this->switched_prod_groups_) {
|
||||||
const Group::ProductionCMode& oldControl = this->prevWGState().group_state.production_control(name);
|
const Group::ProductionCMode& oldControl = this->prevWGState().group_state.production_control(name);
|
||||||
std::string from = Group::ProductionCMode2String(oldControl);
|
std::string from = Group::ProductionCMode2String(oldControl);
|
||||||
if (to.back() != from) {
|
std::string to = Group::ProductionCMode2String(ctrls.back());
|
||||||
|
if (ctrls.back() != oldControl) {
|
||||||
std::string msg = " Production Group " + name
|
std::string msg = " Production Group " + name
|
||||||
+ " control mode changed from ";
|
+ " control mode changed from ";
|
||||||
msg += from;
|
msg += from;
|
||||||
msg += " to " + to.back();
|
msg += " to " + to;
|
||||||
local_deferredLogger.info(msg);
|
local_deferredLogger.info(msg);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for (const auto& [key, to] : this->switched_inj_groups_) {
|
|
||||||
const std::string& name = key.first;
|
|
||||||
const Opm::Phase& phase = key.second;
|
|
||||||
|
|
||||||
const Group::InjectionCMode& oldControl = this->prevWGState().group_state.injection_control(name, phase);
|
for (const auto& [grname, grdata] : this->switched_inj_groups_) {
|
||||||
std::string from = Group::InjectionCMode2String(oldControl);
|
//const std::string& name = key.first;
|
||||||
if (to.back() != from) {
|
//const Opm::Phase& phase = key.second;
|
||||||
std::string msg = " Injection Group " + name
|
const Phase all[] = {Phase::WATER, Phase::OIL, Phase::GAS};
|
||||||
+ " control mode changed from ";
|
for (Phase phase : all) {
|
||||||
msg += from;
|
const auto& ctrls = grdata[static_cast<std::underlying_type_t<Phase>>(phase)];
|
||||||
msg += " to " + to.back();
|
|
||||||
local_deferredLogger.info(msg);
|
if (ctrls.empty()) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if ( !this->prevWGState().group_state.has_injection_control(grname, phase))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
const Group::InjectionCMode& oldControl = this->prevWGState().group_state.injection_control(grname, phase);
|
||||||
|
std::string from = Group::InjectionCMode2String(oldControl);
|
||||||
|
std::string to = Group::InjectionCMode2String(ctrls.back());
|
||||||
|
if (ctrls.back() != oldControl) {
|
||||||
|
std::string msg = " Injection Group " + grname
|
||||||
|
+ " control mode changed from ";
|
||||||
|
msg += from;
|
||||||
|
msg += " to " + to;
|
||||||
|
local_deferredLogger.info(msg);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -332,8 +332,9 @@ public:
|
|||||||
last_valid_wgstate_ = WGState<double>::serializationTestObject(dummy);
|
last_valid_wgstate_ = WGState<double>::serializationTestObject(dummy);
|
||||||
nupcol_wgstate_ = WGState<double>::serializationTestObject(dummy);
|
nupcol_wgstate_ = WGState<double>::serializationTestObject(dummy);
|
||||||
last_glift_opt_time_ = 5.0;
|
last_glift_opt_time_ = 5.0;
|
||||||
switched_prod_groups_ = {{"test4", {"test5", "test6"}}};
|
switched_prod_groups_ = {{"test4", {Group::ProductionCMode::NONE, Group::ProductionCMode::ORAT}}};
|
||||||
switched_inj_groups_ = {{{"test4", Phase::SOLVENT}, {"test5", "test6"}}};
|
const auto controls = {Group::InjectionCMode::NONE, Group::InjectionCMode::RATE, Group::InjectionCMode::RATE };
|
||||||
|
switched_inj_groups_ = {{"test4", {controls, {}, controls} }};
|
||||||
closed_offending_wells_ = {{"test4", {"test5", "test6"}}};
|
closed_offending_wells_ = {{"test4", {"test5", "test6"}}};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user