void WellConnections::init(const Opm::EclipseStateConstPtr eclipseState, const std::array<int, 3>& cartesianSize, const std::vector<int>& cartesian_to_compressed) { std::vector<const Opm::Well*> wells = eclipseState->getSchedule()->getWells(); int last_time_step = eclipseState->getSchedule()->getTimeMap()->size()-1; well_indices_.resize(wells.size()); // We assume that we know all the wells. int index=0; for (const auto well : wells) { std::set<int>& well_indices = well_indices_[index]; Opm::CompletionSetConstPtr completionSet = well->getCompletions(last_time_step); for (size_t c=0; c<completionSet->size(); c++) { Opm::CompletionConstPtr completion = completionSet->get(c); int i = completion->getI(); int j = completion->getJ(); int k = completion->getK(); int cart_grid_idx = i + cartesianSize[0]*(j + cartesianSize[1]*k); int compressed_idx = cartesian_to_compressed[cart_grid_idx]; if ( compressed_idx >= 0 ) // Ignore completions in inactive cells. { well_indices.insert(compressed_idx); } } ++index; } }
CombinedGridWellGraph::CombinedGridWellGraph(const CpGrid& grid, const Opm::EclipseStateConstPtr eclipseState, const double* transmissibilities, bool pretendEmptyGrid) : grid_(grid), eclipseState_(eclipseState), transmissibilities_(transmissibilities) { if ( pretendEmptyGrid ) { // wellsGraph not needed return; } wellsGraph_.resize(grid.numCells()); const auto& cpgdim = grid.logicalCartesianSize(); // create compressed lookup from cartesian. std::vector<Opm::WellConstPtr> wells = eclipseState->getSchedule()->getWells(); std::vector<int> cartesian_to_compressed(cpgdim[0]*cpgdim[1]*cpgdim[2], -1); int last_time_step = eclipseState->getSchedule()->getTimeMap()->size()-1; for( int i=0; i < grid.numCells(); ++i ) { cartesian_to_compressed[grid.globalCell()[i]] = i; } // We assume that we know all the wells. for (auto wellIter= wells.begin(); wellIter != wells.end(); ++wellIter) { Opm::WellConstPtr well = (*wellIter); std::set<int> well_indices; Opm::CompletionSetConstPtr completionSet = well->getCompletions(last_time_step); for (size_t c=0; c<completionSet->size(); c++) { Opm::CompletionConstPtr completion = completionSet->get(c); int i = completion->getI(); int j = completion->getJ(); int k = completion->getK(); int cart_grid_idx = i + cpgdim[0]*(j + cpgdim[1]*k); int compressed_idx = cartesian_to_compressed[cart_grid_idx]; if ( compressed_idx >= 0 ) // Ignore completions in inactive cells. { well_indices.insert(compressed_idx); } } addCompletionSetToGraph(well_indices); } }
void CombinedGridWellGraph::postProcessPartitioningForWells(std::vector<int>& parts) { if( ! wellsGraph_.size() ) { // No wells to be processed return; } // create compressed lookup from cartesian. const auto& cpgdim = grid_.logicalCartesianSize(); std::vector<Opm::WellConstPtr> wells = eclipseState_->getSchedule()->getWells(); std::vector<int> cartesian_to_compressed(cpgdim[0]*cpgdim[1]*cpgdim[2], -1); for( int i=0; i < grid_.numCells(); ++i ) { cartesian_to_compressed[grid_.globalCell()[i]] = i; } int last_time_step = eclipseState_->getSchedule()->getTimeMap()->size()-1; // Check that all completions of a well have ended up on one process. // If that is not the case for well then move them manually to the // process that already has the most completions on it. for (auto wellIter= wells.begin(); wellIter != wells.end(); ++wellIter) { Opm::WellConstPtr well = (*wellIter); std::set<int> well_indices; Opm::CompletionSetConstPtr completionSet = well->getCompletions(last_time_step); if( ! completionSet->size() ) { continue; } std::map<int,std::size_t> no_completions_on_proc; for ( size_t c = 0; c < completionSet->size(); c++ ) { Opm::CompletionConstPtr completion = completionSet->get(c); int i = completion->getI(); int j = completion->getJ(); int k = completion->getK(); int cart_grid_idx = i + cpgdim[0]*(j + cpgdim[1]*k); int compressed_idx = cartesian_to_compressed[cart_grid_idx]; if ( compressed_idx < 0 ) // ignore completions in inactive cells { continue; } ++no_completions_on_proc[parts[compressed_idx]]; } if ( no_completions_on_proc.size() > 1 ) { // partition with the most completions on it becomes new owner int new_owner = std::max_element(no_completions_on_proc.begin(), no_completions_on_proc.end(), [](const std::pair<int,std::size_t>& p1, const std::pair<int,std::size_t>& p2){ return ( p1.second > p2.second ); })->first; std::cout << "Manually moving well " << well->name() << " to partition " << new_owner << std::endl; for ( size_t c = 0; c < completionSet->size(); c++ ) { Opm::CompletionConstPtr completion = completionSet->get(c); int i = completion->getI(); int j = completion->getJ(); int k = completion->getK(); int cart_grid_idx = i + cpgdim[0]*(j + cpgdim[1]*k); int compressed_idx = cartesian_to_compressed[cart_grid_idx]; if ( compressed_idx < 0 ) // ignore completions in inactive cells { continue; } parts[compressed_idx] = new_owner; } } } }