mirror of
https://github.com/OPM/opm-simulators.git
synced 2025-02-25 18:55:30 -06:00
Correct pressure and pvt region index for distributed wells.
To get this we need to determine which process has the very first open well connection and use that to broadcast pressure and pvt region index.
This commit is contained in:
parent
a9a733ebc1
commit
4edca71a1b
@ -573,7 +573,7 @@ namespace Opm {
|
|||||||
const auto phaseUsage = phaseUsageFromDeck(eclState());
|
const auto phaseUsage = phaseUsageFromDeck(eclState());
|
||||||
const size_t numCells = Opm::UgGridHelpers::numCells(grid());
|
const size_t numCells = Opm::UgGridHelpers::numCells(grid());
|
||||||
const bool handle_ms_well = (param_.use_multisegment_well_ && anyMSWellOpenLocal());
|
const bool handle_ms_well = (param_.use_multisegment_well_ && anyMSWellOpenLocal());
|
||||||
well_state_.resize(wells_ecl_, schedule(), handle_ms_well, numCells, phaseUsage, well_perf_data_, summaryState, globalNumWells); // Resize for restart step
|
well_state_.resize(wells_ecl_, local_parallel_well_info_, schedule(), handle_ms_well, numCells, phaseUsage, well_perf_data_, summaryState, globalNumWells); // Resize for restart step
|
||||||
wellsToState(restartValues.wells, restartValues.grp_nwrk, phaseUsage, handle_ms_well, well_state_);
|
wellsToState(restartValues.wells, restartValues.grp_nwrk, phaseUsage, handle_ms_well, well_state_);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -616,6 +616,8 @@ namespace Opm {
|
|||||||
well_perf_data_[well_index].clear();
|
well_perf_data_[well_index].clear();
|
||||||
well_perf_data_[well_index].reserve(well.getConnections().size());
|
well_perf_data_[well_index].reserve(well.getConnections().size());
|
||||||
CheckDistributedWellConnections checker(well, *local_parallel_well_info_[well_index]);
|
CheckDistributedWellConnections checker(well, *local_parallel_well_info_[well_index]);
|
||||||
|
bool hasFirstPerforation = false;
|
||||||
|
bool firstOpenCompletion = true;
|
||||||
|
|
||||||
for (const auto& completion : well.getConnections()) {
|
for (const auto& completion : well.getConnections()) {
|
||||||
const int i = completion.getI();
|
const int i = completion.getI();
|
||||||
@ -625,6 +627,10 @@ namespace Opm {
|
|||||||
const int active_index = cartesian_to_compressed_[cart_grid_indx];
|
const int active_index = cartesian_to_compressed_[cart_grid_indx];
|
||||||
if (completion.state() == Connection::State::OPEN) {
|
if (completion.state() == Connection::State::OPEN) {
|
||||||
if (active_index >= 0) {
|
if (active_index >= 0) {
|
||||||
|
if (firstOpenCompletion)
|
||||||
|
{
|
||||||
|
hasFirstPerforation = true;
|
||||||
|
}
|
||||||
checker.connectionFound(completion_index);
|
checker.connectionFound(completion_index);
|
||||||
PerforationData pd;
|
PerforationData pd;
|
||||||
pd.cell_index = active_index;
|
pd.cell_index = active_index;
|
||||||
@ -633,6 +639,7 @@ namespace Opm {
|
|||||||
pd.ecl_index = completion_index;
|
pd.ecl_index = completion_index;
|
||||||
well_perf_data_[well_index].push_back(pd);
|
well_perf_data_[well_index].push_back(pd);
|
||||||
}
|
}
|
||||||
|
firstOpenCompletion = false;
|
||||||
} else {
|
} else {
|
||||||
checker.connectionFound(completion_index);
|
checker.connectionFound(completion_index);
|
||||||
if (completion.state() != Connection::State::SHUT) {
|
if (completion.state() != Connection::State::SHUT) {
|
||||||
@ -643,6 +650,7 @@ namespace Opm {
|
|||||||
++completion_index;
|
++completion_index;
|
||||||
}
|
}
|
||||||
checker.checkAllConnectionsFound();
|
checker.checkAllConnectionsFound();
|
||||||
|
local_parallel_well_info_[well_index]->communicateFirstPerforation(hasFirstPerforation);
|
||||||
++well_index;
|
++well_index;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -687,7 +695,7 @@ namespace Opm {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
well_state_.init(cellPressures, schedule(), wells_ecl_, timeStepIdx,
|
well_state_.init(cellPressures, schedule(), wells_ecl_, local_parallel_well_info_, timeStepIdx,
|
||||||
&previous_well_state_, phase_usage_, well_perf_data_,
|
&previous_well_state_, phase_usage_, well_perf_data_,
|
||||||
summaryState, globalNumWells);
|
summaryState, globalNumWells);
|
||||||
}
|
}
|
||||||
@ -840,12 +848,18 @@ namespace Opm {
|
|||||||
// Use the pvtRegionIdx from the top cell
|
// Use the pvtRegionIdx from the top cell
|
||||||
const auto& perf_data = this->well_perf_data_[wellID];
|
const auto& perf_data = this->well_perf_data_[wellID];
|
||||||
|
|
||||||
|
// Cater for case where local part might have no perforations.
|
||||||
|
const int pvtreg = perf_data.size() ?
|
||||||
|
pvt_region_idx_[perf_data.front().cell_index] : 0;
|
||||||
|
const auto& parallel_well_info = *local_parallel_well_info_[wellID];
|
||||||
|
auto global_pvtreg = parallel_well_info.broadcastFirstPerforationValue(pvtreg);
|
||||||
|
|
||||||
return std::make_unique<WellType>(this->wells_ecl_[wellID],
|
return std::make_unique<WellType>(this->wells_ecl_[wellID],
|
||||||
*local_parallel_well_info_[wellID],
|
parallel_well_info,
|
||||||
time_step,
|
time_step,
|
||||||
this->param_,
|
this->param_,
|
||||||
*this->rateConverter_,
|
*this->rateConverter_,
|
||||||
this->pvt_region_idx_[perf_data.front().cell_index],
|
global_pvtreg,
|
||||||
this->numComponents(),
|
this->numComponents(),
|
||||||
this->numPhases(),
|
this->numPhases(),
|
||||||
wellID,
|
wellID,
|
||||||
|
@ -25,6 +25,7 @@
|
|||||||
#include <opm/parser/eclipse/EclipseState/Schedule/Schedule.hpp>
|
#include <opm/parser/eclipse/EclipseState/Schedule/Schedule.hpp>
|
||||||
#include <opm/parser/eclipse/EclipseState/Schedule/Well/Well.hpp>
|
#include <opm/parser/eclipse/EclipseState/Schedule/Well/Well.hpp>
|
||||||
#include <opm/simulators/wells/PerforationData.hpp>
|
#include <opm/simulators/wells/PerforationData.hpp>
|
||||||
|
#include <opm/simulators/wells/ParallelWellInfo.hpp>
|
||||||
|
|
||||||
#include <array>
|
#include <array>
|
||||||
#include <cassert>
|
#include <cassert>
|
||||||
@ -51,6 +52,7 @@ namespace Opm
|
|||||||
/// with -1e100.
|
/// with -1e100.
|
||||||
void init(const std::vector<double>& cellPressures,
|
void init(const std::vector<double>& cellPressures,
|
||||||
const std::vector<Well>& wells_ecl,
|
const std::vector<Well>& wells_ecl,
|
||||||
|
const std::vector<ParallelWellInfo*>& parallel_well_info,
|
||||||
const PhaseUsage& pu,
|
const PhaseUsage& pu,
|
||||||
const std::vector<std::vector<PerforationData>>& well_perf_data,
|
const std::vector<std::vector<PerforationData>>& well_perf_data,
|
||||||
const SummaryState& summary_state)
|
const SummaryState& summary_state)
|
||||||
@ -76,7 +78,7 @@ namespace Opm
|
|||||||
const Well& well = wells_ecl[w];
|
const Well& well = wells_ecl[w];
|
||||||
|
|
||||||
// Initialize bhp(), thp(), wellRates(), temperature().
|
// Initialize bhp(), thp(), wellRates(), temperature().
|
||||||
initSingleWell(cellPressures, w, well, pu, summary_state);
|
initSingleWell(cellPressures, w, well, *parallel_well_info[w], pu, summary_state);
|
||||||
|
|
||||||
// Setup wellname -> well index mapping.
|
// Setup wellname -> well index mapping.
|
||||||
const int num_perf_this_well = well_perf_data[w].size();
|
const int num_perf_this_well = well_perf_data[w].size();
|
||||||
@ -285,6 +287,7 @@ namespace Opm
|
|||||||
void initSingleWell(const std::vector<double>& cellPressures,
|
void initSingleWell(const std::vector<double>& cellPressures,
|
||||||
const int w,
|
const int w,
|
||||||
const Well& well,
|
const Well& well,
|
||||||
|
const ParallelWellInfo& well_info,
|
||||||
const PhaseUsage& pu,
|
const PhaseUsage& pu,
|
||||||
const SummaryState& summary_state)
|
const SummaryState& summary_state)
|
||||||
{
|
{
|
||||||
@ -319,7 +322,9 @@ namespace Opm
|
|||||||
: (prod_controls.cmode == Well::ProducerCMode::GRUP);
|
: (prod_controls.cmode == Well::ProducerCMode::GRUP);
|
||||||
|
|
||||||
const double inj_surf_rate = well.isInjector() ? inj_controls.surface_rate : 0.0; // To avoid a "maybe-uninitialized" warning.
|
const double inj_surf_rate = well.isInjector() ? inj_controls.surface_rate : 0.0; // To avoid a "maybe-uninitialized" warning.
|
||||||
|
const double local_pressure = well_perf_data_[w].size() ?
|
||||||
|
cellPressures[well_perf_data_[w][0].cell_index] : 0;
|
||||||
|
const double global_pressure = well_info.broadcastFirstPerforationValue(local_pressure);
|
||||||
if (well.getStatus() == Well::Status::STOP) {
|
if (well.getStatus() == Well::Status::STOP) {
|
||||||
// Stopped well:
|
// Stopped well:
|
||||||
// 1. Rates: zero well rates.
|
// 1. Rates: zero well rates.
|
||||||
@ -329,8 +334,7 @@ namespace Opm
|
|||||||
if (is_bhp) {
|
if (is_bhp) {
|
||||||
bhp_[w] = bhp_limit;
|
bhp_[w] = bhp_limit;
|
||||||
} else {
|
} else {
|
||||||
const int first_cell = well_perf_data_[w][0].cell_index;
|
bhp_[w] = global_pressure;
|
||||||
bhp_[w] = cellPressures[first_cell];
|
|
||||||
}
|
}
|
||||||
} else if (is_grup) {
|
} else if (is_grup) {
|
||||||
// Well under group control.
|
// Well under group control.
|
||||||
@ -339,9 +343,8 @@ namespace Opm
|
|||||||
// little above or below (depending on if
|
// little above or below (depending on if
|
||||||
// the well is an injector or producer)
|
// the well is an injector or producer)
|
||||||
// pressure in first perforation cell.
|
// pressure in first perforation cell.
|
||||||
const int first_cell = well_perf_data_[w][0].cell_index;
|
|
||||||
const double safety_factor = well.isInjector() ? 1.01 : 0.99;
|
const double safety_factor = well.isInjector() ? 1.01 : 0.99;
|
||||||
bhp_[w] = safety_factor*cellPressures[first_cell];
|
bhp_[w] = safety_factor * global_pressure;
|
||||||
} else {
|
} else {
|
||||||
// Open well, under own control:
|
// Open well, under own control:
|
||||||
// 1. Rates: initialize well rates to match
|
// 1. Rates: initialize well rates to match
|
||||||
@ -400,9 +403,8 @@ namespace Opm
|
|||||||
if (is_bhp) {
|
if (is_bhp) {
|
||||||
bhp_[w] = bhp_limit;
|
bhp_[w] = bhp_limit;
|
||||||
} else {
|
} else {
|
||||||
const int first_cell = well_perf_data_[w][0].cell_index;
|
|
||||||
const double safety_factor = well.isInjector() ? 1.01 : 0.99;
|
const double safety_factor = well.isInjector() ? 1.01 : 0.99;
|
||||||
bhp_[w] = safety_factor*cellPressures[first_cell];
|
bhp_[w] = safety_factor * global_pressure;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -72,6 +72,7 @@ namespace Opm
|
|||||||
void init(const std::vector<double>& cellPressures,
|
void init(const std::vector<double>& cellPressures,
|
||||||
const Schedule& schedule,
|
const Schedule& schedule,
|
||||||
const std::vector<Well>& wells_ecl,
|
const std::vector<Well>& wells_ecl,
|
||||||
|
const std::vector<ParallelWellInfo*>& parallel_well_info,
|
||||||
const int report_step,
|
const int report_step,
|
||||||
const WellStateFullyImplicitBlackoil* prevState,
|
const WellStateFullyImplicitBlackoil* prevState,
|
||||||
const PhaseUsage& pu,
|
const PhaseUsage& pu,
|
||||||
@ -80,7 +81,7 @@ namespace Opm
|
|||||||
const int globalNumberOfWells)
|
const int globalNumberOfWells)
|
||||||
{
|
{
|
||||||
// call init on base class
|
// call init on base class
|
||||||
BaseType :: init(cellPressures, wells_ecl, pu, well_perf_data, summary_state);
|
BaseType :: init(cellPressures, wells_ecl, parallel_well_info, pu, well_perf_data, summary_state);
|
||||||
|
|
||||||
globalIsInjectionGrup_.assign(globalNumberOfWells,0);
|
globalIsInjectionGrup_.assign(globalNumberOfWells,0);
|
||||||
globalIsProductionGrup_.assign(globalNumberOfWells,0);
|
globalIsProductionGrup_.assign(globalNumberOfWells,0);
|
||||||
@ -319,6 +320,7 @@ namespace Opm
|
|||||||
|
|
||||||
|
|
||||||
void resize(const std::vector<Well>& wells_ecl,
|
void resize(const std::vector<Well>& wells_ecl,
|
||||||
|
const std::vector<ParallelWellInfo*>& parallel_well_info,
|
||||||
const Schedule& schedule,
|
const Schedule& schedule,
|
||||||
const bool handle_ms_well,
|
const bool handle_ms_well,
|
||||||
const size_t numCells,
|
const size_t numCells,
|
||||||
@ -328,7 +330,7 @@ namespace Opm
|
|||||||
const int globalNumWells)
|
const int globalNumWells)
|
||||||
{
|
{
|
||||||
const std::vector<double> tmp(numCells, 0.0); // <- UGLY HACK to pass the size
|
const std::vector<double> tmp(numCells, 0.0); // <- UGLY HACK to pass the size
|
||||||
init(tmp, schedule, wells_ecl, 0, nullptr, pu, well_perf_data, summary_state, globalNumWells);
|
init(tmp, schedule, wells_ecl, parallel_well_info, 0, nullptr, pu, well_perf_data, summary_state, globalNumWells);
|
||||||
|
|
||||||
if (handle_ms_well) {
|
if (handle_ms_well) {
|
||||||
initWellStateMSWell(wells_ecl, pu, nullptr);
|
initWellStateMSWell(wells_ecl, pu, nullptr);
|
||||||
|
@ -122,8 +122,22 @@ namespace {
|
|||||||
std::vector<double>(setup.grid.c_grid()->number_of_cells,
|
std::vector<double>(setup.grid.c_grid()->number_of_cells,
|
||||||
100.0*Opm::unit::barsa);
|
100.0*Opm::unit::barsa);
|
||||||
|
|
||||||
|
auto wells = setup.sched.getWells(timeStep);
|
||||||
|
std::vector<Opm::ParallelWellInfo> pinfos(wells.size());
|
||||||
|
std::vector<Opm::ParallelWellInfo*> ppinfos(wells.size());
|
||||||
|
auto pw = pinfos.begin();
|
||||||
|
auto ppw = ppinfos.begin();
|
||||||
|
|
||||||
|
for (const auto& well : wells)
|
||||||
|
{
|
||||||
|
*pw = {well.name()};
|
||||||
|
*ppw = &(*pw);
|
||||||
|
++pw;
|
||||||
|
++ppw;
|
||||||
|
}
|
||||||
|
|
||||||
state.init(cpress, setup.sched,
|
state.init(cpress, setup.sched,
|
||||||
setup.sched.getWells(timeStep),
|
wells, ppinfos,
|
||||||
timeStep, nullptr, setup.pu, setup.well_perf_data, setup.st, setup.sched.getWells(timeStep).size());
|
timeStep, nullptr, setup.pu, setup.well_perf_data, setup.st, setup.sched.getWells(timeStep).size());
|
||||||
|
|
||||||
state.initWellStateMSWell(setup.sched.getWells(timeStep),
|
state.initWellStateMSWell(setup.sched.getWells(timeStep),
|
||||||
|
Loading…
Reference in New Issue
Block a user