mirror of
https://github.com/OPM/opm-simulators.git
synced 2025-02-25 18:55:30 -06:00
Merge pull request #3221 from joakim-hove/distribute-events
Distribute events
This commit is contained in:
commit
b832b00ca3
@ -814,14 +814,14 @@ namespace Opm {
|
||||
if (this->wellTestState_.hasWellClosed(well_name)) {
|
||||
// TODO: more checking here, to make sure this standard more specific and complete
|
||||
// maybe there is some WCON keywords will not open the well
|
||||
auto& events = this->wellState().events();
|
||||
if (events.hasEvent(well_name, WellStateFullyImplicitBlackoil::event_mask)) {
|
||||
auto& events = this->wellState().events(w);
|
||||
if (events.hasEvent(WellStateFullyImplicitBlackoil::event_mask)) {
|
||||
if (wellTestState_.lastTestTime(well_name) == ebosSimulator_.time()) {
|
||||
// The well was shut this timestep, we are most likely retrying
|
||||
// a timestep without the well in question, after it caused
|
||||
// repeated timestep cuts. It should therefore not be opened,
|
||||
// even if it was new or received new targets this report step.
|
||||
events.clearEvent(well_name, WellStateFullyImplicitBlackoil::event_mask);
|
||||
events.clearEvent(WellStateFullyImplicitBlackoil::event_mask);
|
||||
} else {
|
||||
wellTestState_.openWell(well_name);
|
||||
}
|
||||
@ -1678,12 +1678,12 @@ namespace Opm {
|
||||
|
||||
if (!well->isOperable() ) continue;
|
||||
|
||||
auto& events = this->wellState().events();
|
||||
if (events.hasEvent(well->name(), WellStateFullyImplicitBlackoil::event_mask)) {
|
||||
auto& events = this->wellState().events(w);
|
||||
if (events.hasEvent(WellStateFullyImplicitBlackoil::event_mask)) {
|
||||
well->updateWellStateWithTarget(ebosSimulator_, this->wellState(), deferred_logger);
|
||||
// There is no new well control change input within a report step,
|
||||
// so next time step, the well does not consider to have effective events anymore.
|
||||
events.clearEvent(well->name(), WellStateFullyImplicitBlackoil::event_mask);
|
||||
events.clearEvent(WellStateFullyImplicitBlackoil::event_mask);
|
||||
}
|
||||
|
||||
// solve the well equation initially to improve the initial solution of the well model
|
||||
|
@ -56,6 +56,14 @@ public:
|
||||
this->data.push_back(std::forward<T>(value));
|
||||
}
|
||||
|
||||
void add(const std::string& name, const T& value) {
|
||||
if (index_map.count(name) != 0)
|
||||
throw std::logic_error("An object with name: " + name + " already exists in container");
|
||||
|
||||
this->index_map.emplace(name, this->data.size());
|
||||
this->data.push_back(value);
|
||||
}
|
||||
|
||||
bool has(const std::string& name) const {
|
||||
return (index_map.count(name) != 0);
|
||||
}
|
||||
@ -66,10 +74,19 @@ public:
|
||||
this->data[index] = std::forward<T>(value);
|
||||
}
|
||||
|
||||
void update(const std::string& name, const T& value) {
|
||||
auto index = this->index_map.at(name);
|
||||
this->data[index] = value;
|
||||
}
|
||||
|
||||
void update(std::size_t index, T&& value) {
|
||||
this->data.at(index) = std::forward<T>(value);
|
||||
}
|
||||
|
||||
void update(std::size_t index, const T& value) {
|
||||
this->data.at(index) = value;
|
||||
}
|
||||
|
||||
/*
|
||||
Will copy the value from other to this - for all wells which are present
|
||||
in both containers.
|
||||
|
@ -24,6 +24,7 @@
|
||||
#include <opm/simulators/wells/WellState.hpp>
|
||||
#include <opm/simulators/wells/ALQState.hpp>
|
||||
#include <opm/simulators/wells/GlobalWellInfo.hpp>
|
||||
#include <opm/simulators/wells/WellContainer.hpp>
|
||||
#include <opm/core/props/BlackoilPhases.hpp>
|
||||
|
||||
#include <opm/parser/eclipse/EclipseState/Schedule/Schedule.hpp>
|
||||
@ -115,7 +116,17 @@ namespace Opm
|
||||
well_dissolved_gas_rates_.resize(nw, 0.0);
|
||||
well_vaporized_oil_rates_.resize(nw, 0.0);
|
||||
|
||||
this->events_ = schedule[report_step].wellgroup_events();
|
||||
this->events_.clear();
|
||||
{
|
||||
const auto& wg_events = schedule[report_step].wellgroup_events();
|
||||
for (const auto& ecl_well : wells_ecl) {
|
||||
const auto& wname = ecl_well.name();
|
||||
if (wg_events.has(wname))
|
||||
this->events_.add( wname, wg_events.at(wname) );
|
||||
else
|
||||
this->events_.add( wname, Events() );
|
||||
}
|
||||
}
|
||||
// Ensure that we start out with zero rates by default.
|
||||
perfphaserates_.clear();
|
||||
perfphaserates_.resize(nperf * this->numPhases(), 0.0);
|
||||
@ -230,7 +241,7 @@ namespace Opm
|
||||
thp()[ newIndex ] = prevState->thp()[ oldIndex ];
|
||||
|
||||
// If new target is set using WCONPROD, WCONINJE etc. we use the new control
|
||||
if (!this->events_.hasEvent(well.name(), WellStateFullyImplicitBlackoil::event_mask)) {
|
||||
if (!this->events_[w].hasEvent(WellStateFullyImplicitBlackoil::event_mask)) {
|
||||
current_injection_controls_[ newIndex ] = prevState->currentInjectionControls()[ oldIndex ];
|
||||
current_production_controls_[ newIndex ] = prevState->currentProductionControls()[ oldIndex ];
|
||||
}
|
||||
@ -789,8 +800,8 @@ namespace Opm
|
||||
}
|
||||
|
||||
|
||||
WellGroupEvents& events() {
|
||||
return this->events_;
|
||||
Events& events(std::size_t well_index) {
|
||||
return this->events_[well_index];
|
||||
}
|
||||
|
||||
const std::vector<int>& firstPerfIndex() const
|
||||
@ -1175,7 +1186,7 @@ namespace Opm
|
||||
// some events happens to the well, like this well is a new well
|
||||
// or new well control keywords happens
|
||||
// \Note: for now, only WCON* keywords, and well status change is considered
|
||||
WellGroupEvents events_;
|
||||
WellContainer<Events> events_;
|
||||
|
||||
// MS well related
|
||||
// for StandardWell, the number of segments will be one
|
||||
|
Loading…
Reference in New Issue
Block a user