mirror of
https://github.com/OPM/opm-simulators.git
synced 2025-02-25 18:55:30 -06:00
Update Well Topology if Triggered From ACTIONX
This commit adds a new flag data member, wellStructureChangedDynamically_ to the generic black-oil well model. This flag captures the well_structure_changed value from the 'SimulatorUpdate' structure in the updateEclWells() member function. Then, in BlackoilWellModel::beginTimeStep(), we key a well structure update off this flag when set. This, in turn, enables creating or opening wells as a result of an ACTIONX block updating the structure in the middle of a report step.
This commit is contained in:
parent
b22f9853db
commit
abfb5c9d82
@ -188,21 +188,24 @@ void EclActionHandler::applySimulatorUpdate(const int report_step,
|
||||
const SimulatorUpdate& sim_update,
|
||||
bool& commit_wellstate,
|
||||
const TransFunc& updateTrans)
|
||||
{
|
||||
OPM_TIMEBLOCK(applySimulatorUpdate);
|
||||
this->wellModel_.updateEclWells(report_step, sim_update.affected_wells, summaryState_);
|
||||
if (!sim_update.affected_wells.empty())
|
||||
commit_wellstate = true;
|
||||
{
|
||||
OPM_TIMEBLOCK(applySimulatorUpdate);
|
||||
|
||||
if (sim_update.tran_update) {
|
||||
const auto& keywords = schedule_[report_step].geo_keywords();
|
||||
ecl_state_.apply_schedule_keywords( keywords );
|
||||
eclBroadcast(comm_, ecl_state_.getTransMult() );
|
||||
this->wellModel_.updateEclWells(report_step, sim_update, this->summaryState_);
|
||||
|
||||
// re-compute transmissibility
|
||||
updateTrans(true);
|
||||
}
|
||||
}
|
||||
if (!sim_update.affected_wells.empty()) {
|
||||
commit_wellstate = true;
|
||||
}
|
||||
|
||||
if (sim_update.tran_update) {
|
||||
const auto& keywords = schedule_[report_step].geo_keywords();
|
||||
ecl_state_.apply_schedule_keywords( keywords );
|
||||
eclBroadcast(comm_, ecl_state_.getTransMult() );
|
||||
|
||||
// re-compute transmissibility
|
||||
updateTrans(true);
|
||||
}
|
||||
}
|
||||
|
||||
std::unordered_map<std::string, double>
|
||||
EclActionHandler::fetchWellPI(const int reportStep,
|
||||
|
@ -32,6 +32,9 @@
|
||||
#include <opm/output/eclipse/RestartValue.hpp>
|
||||
|
||||
#include <opm/input/eclipse/EclipseState/EclipseState.hpp>
|
||||
#include <opm/input/eclipse/EclipseState/SummaryConfig/SummaryConfig.hpp>
|
||||
|
||||
#include <opm/input/eclipse/Schedule/Action/SimulatorUpdate.hpp>
|
||||
#include <opm/input/eclipse/Schedule/Group/GConSale.hpp>
|
||||
#include <opm/input/eclipse/Schedule/Group/GroupEconProductionLimits.hpp>
|
||||
#include <opm/input/eclipse/Schedule/Group/GConSump.hpp>
|
||||
@ -42,7 +45,7 @@
|
||||
#include <opm/input/eclipse/Schedule/Schedule.hpp>
|
||||
#include <opm/input/eclipse/Schedule/Well/WellConnections.hpp>
|
||||
#include <opm/input/eclipse/Schedule/Well/WellTestConfig.hpp>
|
||||
#include <opm/input/eclipse/EclipseState/SummaryConfig/SummaryConfig.hpp>
|
||||
|
||||
#include <opm/input/eclipse/Units/Units.hpp>
|
||||
|
||||
#include <opm/simulators/utils/DeferredLogger.hpp>
|
||||
@ -669,10 +672,10 @@ checkGroupHigherConstraints(const Group& group,
|
||||
void
|
||||
BlackoilWellModelGeneric::
|
||||
updateEclWells(const int timeStepIdx,
|
||||
const std::unordered_set<std::string>& wells,
|
||||
const SimulatorUpdate& sim_update,
|
||||
const SummaryState& st)
|
||||
{
|
||||
for (const auto& wname : wells) {
|
||||
for (const auto& wname : sim_update.affected_wells) {
|
||||
auto well_iter = std::find_if(this->wells_ecl_.begin(), this->wells_ecl_.end(),
|
||||
[&wname] (const auto& well) -> bool
|
||||
{
|
||||
@ -683,25 +686,36 @@ updateEclWells(const int timeStepIdx,
|
||||
continue;
|
||||
}
|
||||
|
||||
auto well_index = std::distance(this->wells_ecl_.begin(), well_iter);
|
||||
this->wells_ecl_[well_index] = schedule_.getWell(wname, timeStepIdx);
|
||||
const auto well_index = std::distance(this->wells_ecl_.begin(), well_iter);
|
||||
|
||||
const auto& well = this->wells_ecl_[well_index];
|
||||
auto& pd = this->well_perf_data_[well_index];
|
||||
auto pdIter = pd.begin();
|
||||
for (const auto& conn : well.getConnections()) {
|
||||
if (conn.state() != Connection::State::SHUT) {
|
||||
pdIter->connection_transmissibility_factor = conn.CF();
|
||||
++pdIter;
|
||||
const auto& well = this->wells_ecl_[well_index] =
|
||||
this->schedule_.getWell(wname, timeStepIdx);
|
||||
|
||||
auto& pd = this->well_perf_data_[well_index];
|
||||
|
||||
{
|
||||
auto pdIter = pd.begin();
|
||||
|
||||
for (const auto& conn : well.getConnections()) {
|
||||
if (conn.state() != Connection::State::SHUT) {
|
||||
pdIter->connection_transmissibility_factor = conn.CF();
|
||||
++pdIter;
|
||||
}
|
||||
}
|
||||
}
|
||||
auto& ws = this->wellState().well(well_index);
|
||||
|
||||
ws.updateStatus( well.getStatus() );
|
||||
ws.reset_connection_factors(pd);
|
||||
ws.update_targets(well, st);
|
||||
{
|
||||
auto& ws = this->wellState().well(well_index);
|
||||
|
||||
ws.updateStatus(well.getStatus());
|
||||
ws.reset_connection_factors(pd);
|
||||
ws.update_targets(well, st);
|
||||
}
|
||||
|
||||
this->prod_index_calc_[well_index].reInit(well);
|
||||
}
|
||||
|
||||
this->wellStructureChangedDynamically_ = sim_update.well_structure_changed;
|
||||
}
|
||||
|
||||
double
|
||||
|
@ -54,14 +54,15 @@
|
||||
namespace Opm {
|
||||
class DeferredLogger;
|
||||
class EclipseState;
|
||||
class GasLiftGroupInfo;
|
||||
class GasLiftSingleWellGeneric;
|
||||
class GasLiftWellState;
|
||||
class GasLiftGroupInfo;
|
||||
class Group;
|
||||
class GuideRateConfig;
|
||||
class ParallelWellInfo;
|
||||
class RestartValue;
|
||||
class Schedule;
|
||||
struct SimulatorUpdate;
|
||||
class SummaryConfig;
|
||||
class VFPProperties;
|
||||
class WellInterfaceGeneric;
|
||||
@ -152,7 +153,7 @@ public:
|
||||
double wellPI(const std::string& well_name) const;
|
||||
|
||||
void updateEclWells(const int timeStepIdx,
|
||||
const std::unordered_set<std::string>& wells,
|
||||
const SimulatorUpdate& sim_update,
|
||||
const SummaryState& st);
|
||||
|
||||
void initFromRestartFile(const RestartValue& restartValues,
|
||||
@ -579,6 +580,8 @@ protected:
|
||||
|
||||
double last_glift_opt_time_ = -1.0;
|
||||
|
||||
bool wellStructureChangedDynamically_{false};
|
||||
|
||||
std::map<std::string, std::string> switched_prod_groups_;
|
||||
std::map<std::pair<std::string, Opm::Phase>, std::string> switched_inj_groups_;
|
||||
|
||||
|
@ -272,6 +272,8 @@ namespace Opm {
|
||||
// Store the current well and group states in order to recover in
|
||||
// the case of failed iterations
|
||||
this->commitWGState();
|
||||
|
||||
this->wellStructureChangedDynamically_ = false;
|
||||
}
|
||||
|
||||
|
||||
@ -371,16 +373,46 @@ namespace Opm {
|
||||
beginTimeStep()
|
||||
{
|
||||
OPM_TIMEBLOCK(beginTimeStep);
|
||||
updateAverageFormationFactor();
|
||||
|
||||
this->updateAverageFormationFactor();
|
||||
|
||||
DeferredLogger local_deferredLogger;
|
||||
switched_prod_groups_.clear();
|
||||
switched_inj_groups_.clear();
|
||||
|
||||
this->switched_prod_groups_.clear();
|
||||
this->switched_inj_groups_.clear();
|
||||
|
||||
if (this->wellStructureChangedDynamically_) {
|
||||
// Something altered the well structure/topology. Possibly
|
||||
// WELSPECS/COMPDAT and/or WELOPEN run from an ACTIONX block.
|
||||
// Reconstruct the local wells to account for the new well
|
||||
// structure.
|
||||
const auto reportStepIdx =
|
||||
this->ebosSimulator_.episodeIndex();
|
||||
|
||||
// Disable WELPI scaling when well structure is updated in the
|
||||
// middle of a report step.
|
||||
const auto enableWellPIScaling = false;
|
||||
|
||||
this->initializeLocalWellStructure(reportStepIdx, enableWellPIScaling);
|
||||
this->initializeGroupStructure(reportStepIdx);
|
||||
|
||||
this->commitWGState();
|
||||
|
||||
// Reset topology flag to signal that we've handled this
|
||||
// structure change. That way we don't end up here in
|
||||
// subsequent calls to beginTimeStep() unless there's a new
|
||||
// dynamic change to the well structure during a report step.
|
||||
this->wellStructureChangedDynamically_ = false;
|
||||
}
|
||||
|
||||
this->resetWGState();
|
||||
|
||||
const int reportStepIdx = ebosSimulator_.episodeIndex();
|
||||
updateAndCommunicateGroupData(reportStepIdx,
|
||||
ebosSimulator_.model().newtonMethod().numIterations());
|
||||
|
||||
this->wellState().gliftTimeStepInit();
|
||||
|
||||
const double simulationTime = ebosSimulator_.time();
|
||||
OPM_BEGIN_PARALLEL_TRY_CATCH();
|
||||
{
|
||||
|
Loading…
Reference in New Issue
Block a user