void restoreOPM_XWELKeyword(const std::string& restart_filename, int reportstep, bool unified, WellState& wellstate) { const char * keyword = "OPM_XWEL"; const char* filename = restart_filename.c_str(); ecl_file_type* file_type = ecl_file_open(filename, 0); if (file_type != NULL) { bool block_selected = unified ? ecl_file_select_rstblock_report_step(file_type , reportstep) : true; if (block_selected) { ecl_kw_type* xwel = ecl_file_iget_named_kw(file_type , keyword, 0); const double* xwel_data = ecl_kw_get_double_ptr(xwel); std::copy_n(xwel_data + wellstate.getRestartTemperatureOffset(), wellstate.temperature().size(), wellstate.temperature().begin()); std::copy_n(xwel_data + wellstate.getRestartBhpOffset(), wellstate.bhp().size(), wellstate.bhp().begin()); std::copy_n(xwel_data + wellstate.getRestartPerfPressOffset(), wellstate.perfPress().size(), wellstate.perfPress().begin()); std::copy_n(xwel_data + wellstate.getRestartPerfRatesOffset(), wellstate.perfRates().size(), wellstate.perfRates().begin()); std::copy_n(xwel_data + wellstate.getRestartWellRatesOffset(), wellstate.wellRates().size(), wellstate.wellRates().begin()); } else { std::string error_str = "Restart file " + restart_filename + " does not contain data for report step " + std::to_string(reportstep) + "!\n"; throw std::runtime_error(error_str); } ecl_file_close(file_type); } else { std::string error_str = "Restart file " + restart_filename + " not found!\n"; throw std::runtime_error(error_str); } }
/// Compute two-phase transport source terms from well terms. /// Note: Unlike the incompressible version of this function, /// this version computes surface volume injection rates, /// production rates are still total reservoir volumes. /// \param[in] props Fluid and rock properties. /// \param[in] wells Wells data structure. /// \param[in] well_state Well pressures and fluxes. /// \param[out] transport_src The transport source terms. They are to be interpreted depending on sign: /// (+) positive inflow of first (water) phase (surface volume), /// (-) negative total outflow of both phases (reservoir volume). void computeTransportSource(const BlackoilPropertiesInterface& props, const Wells* wells, const WellState& well_state, std::vector<double>& transport_src) { int nc = props.numCells(); transport_src.clear(); transport_src.resize(nc, 0.0); // Well contributions. if (wells) { const int nw = wells->number_of_wells; const int np = wells->number_of_phases; if (np != 2) { OPM_THROW(std::runtime_error, "computeTransportSource() requires a 2 phase case."); } std::vector<double> A(np*np); for (int w = 0; w < nw; ++w) { const double* comp_frac = wells->comp_frac + np*w; for (int perf = wells->well_connpos[w]; perf < wells->well_connpos[w + 1]; ++perf) { const int perf_cell = wells->well_cells[perf]; double perf_rate = well_state.perfRates()[perf]; if (perf_rate > 0.0) { // perf_rate is a total inflow reservoir rate, we want a surface water rate. if (wells->type[w] != INJECTOR) { std::cout << "**** Warning: crossflow in well " << w << " perf " << perf - wells->well_connpos[w] << " ignored. Reservoir rate was " << perf_rate/Opm::unit::day << " m^3/day." << std::endl; perf_rate = 0.0; } else { assert(std::fabs(comp_frac[0] + comp_frac[1] - 1.0) < 1e-6); perf_rate *= comp_frac[0]; // Water reservoir volume rate. props.matrix(1, &well_state.perfPress()[perf], &well_state.temperature()[w], comp_frac, &perf_cell, &A[0], 0); perf_rate *= A[0]; // Water surface volume rate. } } transport_src[perf_cell] += perf_rate; } } } }