mirror of
https://github.com/OPM/opm-simulators.git
synced 2025-02-25 18:55:30 -06:00
[bugfix,parallel] Deactivate non-existing wells in manager.
Previously, we used the setStatus method to set wells that do not exist on the local grid to SHUT. Or at least this is what I thought that ```well.setStatus(timestep, SHUT)```. Unfortunately, my assumption was wrong. This was revealed while testing a parallel run with SPE9 that threw an expeption about "Elements must be added in weakly increasing order" in Opm::DynamicState::add(int, T). Seems like the method name is a bit misleading. As it turns out the WellManager has its own complete list of active wells (shut wells are simply left out). Therefore we can use this behaviour to our advantage: With this commit we not only exclude shut wells from the list, but also the ones that do not exist on the local grid. We even get rid of an ugly const_cast. Currently, I have running a parallel SPE9 test that has not yet aborted.
This commit is contained in:
parent
ca3bcb2662
commit
63d8d5e781
@ -407,10 +407,19 @@ namespace Opm
|
||||
|
||||
|
||||
void WellsManager::setupWellControls(std::vector<WellConstPtr>& wells, size_t timeStep,
|
||||
std::vector<std::string>& well_names, const PhaseUsage& phaseUsage) {
|
||||
std::vector<std::string>& well_names, const PhaseUsage& phaseUsage,
|
||||
const std::vector<int>& wells_on_proc) {
|
||||
int well_index = 0;
|
||||
for (auto wellIter= wells.begin(); wellIter != wells.end(); ++wellIter) {
|
||||
WellConstPtr well = (*wellIter);
|
||||
auto well_on_proc = wells_on_proc.begin();
|
||||
|
||||
for (auto wellIter= wells.begin(); wellIter != wells.end(); ++wellIter, ++well_on_proc) {
|
||||
if( ! *well_on_proc )
|
||||
{
|
||||
// Wells not stored on the process are not in the list
|
||||
continue;
|
||||
}
|
||||
|
||||
WellConstPtr well = (*wellIter);
|
||||
|
||||
if (well->getStatus(timeStep) == WellCommon::STOP) {
|
||||
// STOPed wells are kept in the well list but marked as stopped.
|
||||
|
@ -155,7 +155,8 @@ namespace Opm
|
||||
WellsManager& operator=(const WellsManager& other);
|
||||
static void setupCompressedToCartesian(const int* global_cell, int number_of_cells, std::map<int,int>& cartesian_to_compressed );
|
||||
void setupWellControls(std::vector<WellConstPtr>& wells, size_t timeStep,
|
||||
std::vector<std::string>& well_names, const PhaseUsage& phaseUsage);
|
||||
std::vector<std::string>& well_names, const PhaseUsage& phaseUsage,
|
||||
const std::vector<int>& wells_on_proc);
|
||||
|
||||
template<class C2F, class FC, class NTG>
|
||||
void createWellsFromSpecs( std::vector<WellConstPtr>& wells, size_t timeStep,
|
||||
@ -169,7 +170,8 @@ namespace Opm
|
||||
const PhaseUsage& phaseUsage,
|
||||
const std::map<int,int>& cartesian_to_compressed,
|
||||
const double* permeability,
|
||||
const NTG& ntg);
|
||||
const NTG& ntg,
|
||||
std::vector<int>& wells_on_proc);
|
||||
|
||||
void addChildGroups(GroupTreeNodeConstPtr parentNode, ScheduleConstPtr schedule, size_t timeStep, const PhaseUsage& phaseUsage);
|
||||
void setupGuideRates(std::vector<WellConstPtr>& wells, const size_t timeStep, std::vector<WellData>& well_data, std::map<std::string, int>& well_names_to_index);
|
||||
|
@ -113,7 +113,8 @@ void WellsManager::createWellsFromSpecs(std::vector<WellConstPtr>& wells, size_t
|
||||
const PhaseUsage& phaseUsage,
|
||||
const std::map<int,int>& cartesian_to_compressed,
|
||||
const double* permeability,
|
||||
const NTG& ntg)
|
||||
const NTG& ntg,
|
||||
std::vector<int>& wells_on_proc)
|
||||
{
|
||||
if (dimensions != 3) {
|
||||
OPM_THROW(std::domain_error,
|
||||
@ -122,9 +123,8 @@ void WellsManager::createWellsFromSpecs(std::vector<WellConstPtr>& wells, size_t
|
||||
}
|
||||
|
||||
std::vector<std::vector<PerfData> > wellperf_data;
|
||||
std::vector<int> well_on_proc;
|
||||
wellperf_data.resize(wells.size());
|
||||
well_on_proc.resize(wells.size(), 1);
|
||||
wells_on_proc.resize(wells.size(), 1);
|
||||
|
||||
int well_index = 0;
|
||||
for (auto wellIter= wells.begin(); wellIter != wells.end(); ++wellIter) {
|
||||
@ -206,7 +206,8 @@ void WellsManager::createWellsFromSpecs(std::vector<WellConstPtr>& wells, size_t
|
||||
completion_on_proc.end(),0);
|
||||
if ( sum_completions_on_proc == 0 )
|
||||
{
|
||||
const_cast<Well&>(*well).setStatus(timeStep, WellCommon::SHUT);
|
||||
// Mark well as not existent on this process
|
||||
wells_on_proc[wellIter-wells.begin()] = 0;
|
||||
continue;
|
||||
}
|
||||
// Check that the complete well is on this process
|
||||
@ -233,7 +234,7 @@ void WellsManager::createWellsFromSpecs(std::vector<WellConstPtr>& wells, size_t
|
||||
|
||||
well_index++;
|
||||
}
|
||||
|
||||
std::cout<<"well_index="<<well_index<<" no wells="<<wells.size()<<std::endl;
|
||||
// Set up reference depths that were defaulted. Count perfs.
|
||||
|
||||
const int num_wells = well_data.size();
|
||||
@ -347,6 +348,7 @@ WellsManager::init(const Opm::EclipseStateConstPtr eclipseState,
|
||||
|
||||
ScheduleConstPtr schedule = eclipseState->getSchedule();
|
||||
std::vector<WellConstPtr> wells = schedule->getWells(timeStep);
|
||||
std::vector<int> wells_on_proc;
|
||||
|
||||
well_names.reserve(wells.size());
|
||||
well_data.reserve(wells.size());
|
||||
@ -362,9 +364,10 @@ WellsManager::init(const Opm::EclipseStateConstPtr eclipseState,
|
||||
begin_face_centroids,
|
||||
dimensions,
|
||||
well_names, well_data, well_names_to_index,
|
||||
pu, cartesian_to_compressed, permeability, ntg);
|
||||
pu, cartesian_to_compressed, permeability, ntg,
|
||||
wells_on_proc);
|
||||
|
||||
setupWellControls(wells, timeStep, well_names, pu);
|
||||
setupWellControls(wells, timeStep, well_names, pu, wells_on_proc);
|
||||
|
||||
{
|
||||
GroupTreeNodeConstPtr fieldNode =
|
||||
|
Loading…
Reference in New Issue
Block a user