[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:
Markus Blatt 2015-05-26 20:45:08 +02:00
parent ca3bcb2662
commit 63d8d5e781
3 changed files with 26 additions and 12 deletions

View File

@ -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.

View File

@ -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);

View File

@ -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 =