void Compsegs::updateConnectionsWithSegment(const std::vector< Compsegs >& compsegs, const EclipseGrid& grid, WellConnections& connection_set) { for( const auto& compseg : compsegs ) { const int i = compseg.m_i; const int j = compseg.m_j; const int k = compseg.m_k; if (grid.cellActive(i, j, k)) { Connection& connection = connection_set.getFromIJK( i, j, k ); connection.updateSegment(compseg.segment_number, compseg.center_depth,compseg.m_seqIndex); //keep connection sequence number from input sequence connection.setCompSegSeqIndex(compseg.m_seqIndex); connection.setSegDistStart(compseg.m_distance_start); connection.setSegDistEnd(compseg.m_distance_end); } } for (size_t ic = 0; ic < connection_set.size(); ++ic) { if ( !(connection_set.get(ic).attachedToSegment()) ) { throw std::runtime_error("Not all the connections are attached with a segment. " "The information from COMPSEGS is not complete"); } } }
std::vector<std::vector<int> > postProcessPartitioningForWells(std::vector<int>& parts, const Opm::EclipseStateConstPtr eclipseState, const WellConnections& well_connections, std::size_t no_procs) { std::vector<const Opm::Well*> wells = eclipseState->getSchedule()->getWells(); // Contains for each process the indices of the wells assigned to it. std::vector<std::vector<int> > well_indices_on_proc(no_procs); if( ! well_connections.size() ) { // No wells to be processed return well_indices_on_proc; } // prevent memory allocation for(auto& well_indices : well_indices_on_proc) { well_indices.reserve(wells.size()); } // 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. int well_index = 0; for (const auto* well: wells) { const auto& well_completions = well_connections[well_index]; std::map<int,std::size_t> no_completions_on_proc; for ( auto completion_index: well_completions ) { ++no_completions_on_proc[parts[completion_index]]; } int owner = no_completions_on_proc.begin()->first; 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 ( auto completion_cell : well_completions ) { parts[completion_cell] = new_owner; } owner = new_owner; } well_indices_on_proc[owner].push_back(well_index); ++well_index; } return well_indices_on_proc; }