Changes to Well status implementation
o The status of a well is maintened as a small object which is managed by a new std::shared_ptr member in the well objects. The consequence of this is that several well objects can share the same underlying status object. The advantage of this is that runtime (i.e. ACTIONX) updates of well status will affect the correct set of wells. o The general Schedule::updateWell() will use the DynamicState::upadte_equal()
This commit is contained in:
@@ -573,20 +573,20 @@ private:
|
||||
}
|
||||
|
||||
void Schedule::shut_well(const std::string& well_name, std::size_t report_step) {
|
||||
this->updateWellStatus(well_name, report_step, Well::Status::SHUT, true);
|
||||
this->updateWellStatus(well_name, report_step, true, Well::Status::SHUT, false);
|
||||
}
|
||||
|
||||
void Schedule::open_well(const std::string& well_name, std::size_t report_step) {
|
||||
this->updateWellStatus(well_name, report_step, Well::Status::OPEN, true);
|
||||
this->updateWellStatus(well_name, report_step, true, Well::Status::OPEN, false);
|
||||
}
|
||||
|
||||
void Schedule::stop_well(const std::string& well_name, std::size_t report_step) {
|
||||
this->updateWellStatus(well_name, report_step, Well::Status::STOP, true);
|
||||
this->updateWellStatus(well_name, report_step, true, Well::Status::STOP, false);
|
||||
}
|
||||
|
||||
void Schedule::updateWell(std::shared_ptr<Well> well, std::size_t reportStep) {
|
||||
auto& dynamic_state = this->wells_static.at(well->name());
|
||||
dynamic_state.update(reportStep, std::move(well));
|
||||
dynamic_state.update_equal(reportStep, std::move(well));
|
||||
}
|
||||
|
||||
|
||||
@@ -594,7 +594,7 @@ private:
|
||||
Function is quite dangerous - because if this is called while holding a
|
||||
Well pointer that will go stale and needs to be refreshed.
|
||||
*/
|
||||
bool Schedule::updateWellStatus( const std::string& well_name, std::size_t reportStep , Well::Status status, bool update_connections, std::optional<KeywordLocation> location) {
|
||||
bool Schedule::updateWellStatus( const std::string& well_name, std::size_t reportStep , bool runtime, Well::Status status, bool update_connections, std::optional<KeywordLocation> location) {
|
||||
auto& dynamic_state = this->wells_static.at(well_name);
|
||||
auto well2 = std::make_shared<Well>(*dynamic_state[reportStep]);
|
||||
if (well2->getConnections().empty() && status == Well::Status::OPEN) {
|
||||
@@ -608,14 +608,26 @@ private:
|
||||
return false;
|
||||
}
|
||||
|
||||
auto old_status = well2->getStatus();
|
||||
bool update = false;
|
||||
if (well2->updateStatus(status, update_connections)) {
|
||||
m_events.addEvent( ScheduleEvents::WELL_STATUS_CHANGE, reportStep );
|
||||
this->addWellGroupEvent( well2->name(), ScheduleEvents::WELL_STATUS_CHANGE, reportStep);
|
||||
if (well2->updateStatus(status, runtime, update_connections)) {
|
||||
this->updateWell(well2, reportStep);
|
||||
update = true;
|
||||
if (status == Well::Status::OPEN)
|
||||
this->rft_config.addWellOpen(well_name, reportStep);
|
||||
|
||||
/*
|
||||
The Well::updateStatus() will always return true because a new
|
||||
WellStatus object should be created. But the new object might have
|
||||
the same value as the previous object; therefor we need to check
|
||||
for an actual status change before we emit a WELL_STATUS_CHANGE
|
||||
event.
|
||||
*/
|
||||
if (old_status != status) {
|
||||
this->m_events.addEvent( ScheduleEvents::WELL_STATUS_CHANGE, reportStep );
|
||||
this->addWellGroupEvent( well2->name(), ScheduleEvents::WELL_STATUS_CHANGE, reportStep);
|
||||
}
|
||||
|
||||
update = true;
|
||||
}
|
||||
return update;
|
||||
}
|
||||
@@ -654,7 +666,7 @@ private:
|
||||
}
|
||||
}
|
||||
|
||||
void Schedule::applyWELOPEN(const DeckKeyword& keyword, std::size_t currentStep, const ParseContext& parseContext, ErrorGuard& errors, const std::vector<std::string>& matching_wells) {
|
||||
void Schedule::applyWELOPEN(const DeckKeyword& keyword, std::size_t currentStep, bool runtime, const ParseContext& parseContext, ErrorGuard& errors, const std::vector<std::string>& matching_wells) {
|
||||
|
||||
auto conn_defaulted = []( const DeckRecord& rec ) {
|
||||
auto defaulted = []( const DeckItem& item ) {
|
||||
@@ -665,7 +677,6 @@ private:
|
||||
};
|
||||
|
||||
constexpr auto open = Well::Status::OPEN;
|
||||
bool action_mode = !matching_wells.empty();
|
||||
|
||||
for (const auto& record : keyword) {
|
||||
const auto& wellNamePattern = record.getItem( "WELL" ).getTrimmedString(0);
|
||||
@@ -690,7 +701,7 @@ private:
|
||||
+ std::to_string( days ) + " days";
|
||||
OpmLog::note(msg);
|
||||
} else {
|
||||
this->updateWellStatus( wname, currentStep, well_status, false );
|
||||
this->updateWellStatus( wname, currentStep, runtime, well_status, false );
|
||||
if (well_status == open)
|
||||
this->rft_config.addWellOpen(wname, currentStep);
|
||||
}
|
||||
@@ -705,7 +716,7 @@ private:
|
||||
{
|
||||
auto& dynamic_state = this->wells_static.at(wname);
|
||||
auto well_ptr = std::make_shared<Well>( *dynamic_state[currentStep] );
|
||||
if (well_ptr->handleWELOPEN(record, comp_status, action_mode))
|
||||
if (well_ptr->handleWELOPEN(record, comp_status, runtime))
|
||||
// The updateWell call breaks test at line 825 and 831 in ScheduleTests
|
||||
this->updateWell(std::move(well_ptr), currentStep);
|
||||
}
|
||||
@@ -876,7 +887,7 @@ private:
|
||||
const std::string wname = well.name();
|
||||
|
||||
m_events.addEvent( ScheduleEvents::NEW_WELL , report_step );
|
||||
wellgroup_events.insert( std::make_pair(wname, Events(this->m_timeMap)));
|
||||
this->wellgroup_events.insert( std::make_pair(wname, Events(this->m_timeMap)));
|
||||
this->addWellGroupEvent(wname, ScheduleEvents::NEW_WELL, report_step);
|
||||
|
||||
well.setInsertIndex(this->wells_static.size());
|
||||
@@ -1372,7 +1383,7 @@ private:
|
||||
"All completions in well " + well.name() + " is shut at " + std::to_string ( m_timeMap.getTimePassedUntil(timeStep) / (60*60*24) ) + " days. \n" +
|
||||
"The well is therefore also shut.";
|
||||
OpmLog::note(msg);
|
||||
this->updateWellStatus( well.name(), timeStep, Well::Status::SHUT, false);
|
||||
this->updateWellStatus( well.name(), timeStep, false, Well::Status::SHUT, false);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1533,7 +1544,7 @@ private:
|
||||
this->updateUDQ(keyword, reportStep);
|
||||
|
||||
if (keyword.name() == "WELOPEN")
|
||||
this->applyWELOPEN(keyword, reportStep, parseContext, errors, result.wells());
|
||||
this->applyWELOPEN(keyword, reportStep, true, parseContext, errors, result.wells());
|
||||
|
||||
/*
|
||||
The WELPI functionality is implemented as a two-step process
|
||||
|
||||
Reference in New Issue
Block a user