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 verifyWellState(const std::string& rst_filename, Opm::EclipseGridConstPtr ecl_grid, Opm::ScheduleConstPtr schedule) { well_info_type * well_info = well_info_alloc(ecl_grid->c_ptr()); well_info_load_rstfile(well_info, rst_filename.c_str(), false); //Verify numwells int numwells = well_info_get_num_wells(well_info); BOOST_CHECK(numwells == (int)schedule->numWells()); std::vector<Opm::WellConstPtr> wells = schedule->getWells(); for (int i = 0; i < numwells; ++i) { //Verify wellnames const char * wellname = well_info_iget_well_name(well_info, i); Opm::WellConstPtr well = wells.at(i); BOOST_CHECK(wellname == well->name()); // Verify well-head position data well_ts_type * well_ts = well_info_get_ts(well_info , wellname); well_state_type * well_state = well_ts_iget_state(well_ts, 0); const well_conn_type * well_head = well_state_get_wellhead(well_state, ECL_GRID_GLOBAL_GRID); BOOST_CHECK(well_conn_get_i(well_head) == well->getHeadI()); BOOST_CHECK(well_conn_get_j(well_head) == well->getHeadJ()); for (int j = 0; j < well_ts_get_size(well_ts); ++j) { well_state = well_ts_iget_state(well_ts, j); //Verify welltype int ert_well_type = well_state_get_type(well_state); WellType welltype = well->isProducer(j) ? PRODUCER : INJECTOR; Opm::WellInjector::TypeEnum injectortype = well->getInjectionProperties(j).injectorType; int ecl_converted_welltype = Opm::EclipseWriter::eclipseWellTypeMask(welltype, injectortype); int ert_converted_welltype = well_state_translate_ecl_type_int(ecl_converted_welltype); BOOST_CHECK(ert_well_type == ert_converted_welltype); //Verify wellstatus int ert_well_status = well_state_is_open(well_state) ? 1 : 0; Opm::WellCommon::StatusEnum status = well->getStatus(j); int wellstatus = Opm::EclipseWriter::eclipseWellStatusMask(status); BOOST_CHECK(ert_well_status == wellstatus); //Verify number of completion connections const well_conn_collection_type * well_connections = well_state_get_global_connections( well_state ); size_t num_wellconnections = well_conn_collection_get_size(well_connections); int report_nr = well_state_get_report_nr(well_state); Opm::CompletionSetConstPtr completions_set = well->getCompletions((size_t)report_nr); BOOST_CHECK(num_wellconnections == completions_set->size()); //Verify coordinates for each completion connection for (size_t k = 0; k < num_wellconnections; ++k) { const well_conn_type * well_connection = well_conn_collection_iget_const(well_connections , k); Opm::CompletionConstPtr completion = completions_set->get(k); BOOST_CHECK(well_conn_get_i(well_connection) == completion->getI()); BOOST_CHECK(well_conn_get_j(well_connection) == completion->getJ()); BOOST_CHECK(well_conn_get_k(well_connection) == completion->getK()); } } } well_info_free(well_info); }
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; } } } }