inline void setupGridAndProps(const Opm::parameter::ParameterGroup& param, CpGrid& grid, ResProp<3>& res_prop) { // Initialize grid and reservoir properties. // Parts copied from CpGrid::init(). std::string fileformat = param.getDefault<std::string>("fileformat", "cartesian"); if (fileformat == "sintef_legacy") { std::string grid_prefix = param.get<std::string>("grid_prefix"); grid.readSintefLegacyFormat(grid_prefix); MESSAGE("Warning: We do not yet read legacy reservoir properties. Using defaults."); res_prop.init(grid.size(0)); } else if (fileformat == "eclipse") { Opm::EclipseGridParser parser(param.get<std::string>("filename")); double z_tolerance = param.getDefault<double>("z_tolerance", 0.0); bool periodic_extension = param.getDefault<bool>("periodic_extension", false); bool turn_normals = param.getDefault<bool>("turn_normals", false); grid.processEclipseFormat(parser, z_tolerance, periodic_extension, turn_normals); double perm_threshold_md = param.getDefault("perm_threshold_md", 0.0); double perm_threshold = Opm::unit::convert::from(perm_threshold_md, Opm::prefix::milli*Opm::unit::darcy); std::string rock_list = param.getDefault<std::string>("rock_list", "no_list"); std::string* rl_ptr = (rock_list == "no_list") ? 0 : &rock_list; bool use_j = param.getDefault("use_jfunction_scaling", useJ<ResProp<3> >()); double sigma = 1.0; double theta = 0.0; if (use_j) { sigma = param.getDefault("sigma", sigma); theta = param.getDefault("theta", theta); } if (param.has("viscosity1") || param.has("viscosity2")) { double v1 = param.getDefault("viscosity1", 0.001); double v2 = param.getDefault("viscosity2", 0.003); res_prop.setViscosities(v1, v2); } res_prop.init(parser, grid.globalCell(), perm_threshold, rl_ptr, use_j, sigma, theta); } else if (fileformat == "cartesian") { array<int, 3> dims = {{ param.getDefault<int>("nx", 1), param.getDefault<int>("ny", 1), param.getDefault<int>("nz", 1) }}; array<double, 3> cellsz = {{ param.getDefault<double>("dx", 1.0), param.getDefault<double>("dy", 1.0), param.getDefault<double>("dz", 1.0) }}; grid.createCartesian(dims, cellsz); double default_poro = param.getDefault("default_poro", 0.2); double default_perm_md = param.getDefault("default_perm_md", 100.0); double default_perm = Opm::unit::convert::from(default_perm_md, Opm::prefix::milli*Opm::unit::darcy); MESSAGE("Warning: For generated cartesian grids, we use uniform reservoir properties."); res_prop.init(grid.size(0), default_poro, default_perm); } else { THROW("Unknown file format string: " << fileformat); } if (param.getDefault("use_unique_boundary_ids", false)) { grid.setUniqueBoundaryIds(true); } }
/// Initialize the grid. void CpGrid::init(const Opm::parameter::ParameterGroup& param) { std::string fileformat = param.get<std::string>("fileformat"); if (fileformat == "sintef_legacy") { std::string grid_prefix = param.get<std::string>("grid_prefix"); readSintefLegacyFormat(grid_prefix); } else if (fileformat == "eclipse") { std::string filename = param.get<std::string>("filename"); if (param.has("z_tolerance")) { std::cerr << "****** Warning: z_tolerance parameter is obsolete, use PINCH in deck input instead\n"; } bool periodic_extension = param.getDefault<bool>("periodic_extension", false); bool turn_normals = param.getDefault<bool>("turn_normals", false); readEclipseFormat(filename, periodic_extension, turn_normals); } else if (fileformat == "cartesian") { array<int, 3> dims = {{ param.getDefault<int>("nx", 1), param.getDefault<int>("ny", 1), param.getDefault<int>("nz", 1) }}; array<double, 3> cellsz = {{ param.getDefault<double>("dx", 1.0), param.getDefault<double>("dy", 1.0), param.getDefault<double>("dz", 1.0) }}; createCartesian(dims, cellsz); } else { OPM_THROW(std::runtime_error, "Unknown file format string: " << fileformat); } }
inline void setupGridAndProps(const Opm::parameter::ParameterGroup& param, Dune::CpGrid& grid, ResProp<3>& res_prop) { // Initialize grid and reservoir properties. // Parts copied from Dune::CpGrid::init(). std::string fileformat = param.getDefault<std::string>("fileformat", "cartesian"); if (fileformat == "sintef_legacy") { std::string grid_prefix = param.get<std::string>("grid_prefix"); grid.readSintefLegacyFormat(grid_prefix); OPM_MESSAGE("Warning: We do not yet read legacy reservoir properties. Using defaults."); res_prop.init(grid.size(0)); } else if (fileformat == "eclipse") { std::string ecl_file = param.get<std::string>("filename"); Opm::ParseContext parseContext; Opm::ParserPtr parser(new Opm::Parser()); Opm::DeckConstPtr deck(parser->parseFile(ecl_file , parseContext)); if (param.has("z_tolerance")) { std::cerr << "****** Warning: z_tolerance parameter is obsolete, use PINCH in deck input instead\n"; } bool periodic_extension = param.getDefault<bool>("periodic_extension", false); bool turn_normals = param.getDefault<bool>("turn_normals", false); grid.processEclipseFormat(deck, periodic_extension, turn_normals); // Save EGRID file in case we are writing ECL output. if (param.getDefault("output_ecl", false)) { OPM_THROW(std::runtime_error, "Saving to EGRID files is not yet implemented"); /* boost::filesystem::path ecl_path(ecl_file); const std::vector<int>& globalCell = grid.globalCell(); ecl_path.replace_extension(".EGRID"); parser.saveEGRID(ecl_path.string() , (int) globalCell.size() , &globalCell[0]); */ } double perm_threshold_md = param.getDefault("perm_threshold_md", 0.0); double perm_threshold = Opm::unit::convert::from(perm_threshold_md, Opm::prefix::milli*Opm::unit::darcy); std::string rock_list = param.getDefault<std::string>("rock_list", "no_list"); std::string* rl_ptr = (rock_list == "no_list") ? 0 : &rock_list; bool use_j = param.getDefault("use_jfunction_scaling", useJ<ResProp<3> >()); double sigma = 1.0; double theta = 0.0; if (use_j) { sigma = param.getDefault("sigma", sigma); theta = param.getDefault("theta", theta); } if (param.has("viscosity1") || param.has("viscosity2")) { double v1 = param.getDefault("viscosity1", 0.001); double v2 = param.getDefault("viscosity2", 0.003); res_prop.setViscosities(v1, v2); } res_prop.init(deck, grid.globalCell(), perm_threshold, rl_ptr, use_j, sigma, theta); } else if (fileformat == "cartesian") { std::array<int, 3> dims = {{ param.getDefault<int>("nx", 1), param.getDefault<int>("ny", 1), param.getDefault<int>("nz", 1) }}; std::array<double, 3> cellsz = {{ param.getDefault<double>("dx", 1.0), param.getDefault<double>("dy", 1.0), param.getDefault<double>("dz", 1.0) }}; grid.createCartesian(dims, cellsz); double default_poro = param.getDefault("default_poro", 0.2); double default_perm_md = param.getDefault("default_perm_md", 100.0); double default_perm = Opm::unit::convert::from(default_perm_md, Opm::prefix::milli*Opm::unit::darcy); OPM_MESSAGE("Warning: For generated cartesian grids, we use uniform reservoir properties."); res_prop.init(grid.size(0), default_poro, default_perm); } else { OPM_THROW(std::runtime_error, "Unknown file format string: " << fileformat); } if (param.getDefault("use_unique_boundary_ids", false)) { grid.setUniqueBoundaryIds(true); } }
void upscale(const Opm::parameter::ParameterGroup& param) { // Control structure. std::vector<double> saturations; Opm::SparseTable<double> all_pdrops; bool from_file = param.has("sat_pdrop_filename"); if (from_file) { std::string filename = param.get<std::string>("sat_pdrop_filename"); std::ifstream file(filename.c_str()); if (!file) { OPM_THROW(std::runtime_error, "Could not open file " << filename); } readControl(file, saturations, all_pdrops); } else { // Get a linear range of saturations. int num_sats = param.getDefault("num_sats", 4); double min_sat = param.getDefault("min_sat", 0.2); double max_sat = param.getDefault("max_sat", 0.8); saturations.resize(num_sats); for (int i = 0; i < num_sats; ++i) { double factor = num_sats == 1 ? 0 : double(i)/double(num_sats - 1); saturations[i] = (1.0 - factor)*min_sat + factor*max_sat; } // Get a logarithmic range of pressure drops. int num_pdrops = param.getDefault("num_pdrops", 5); double log_min_pdrop = std::log(param.getDefault("min_pdrop", 1e2)); double log_max_pdrop = std::log(param.getDefault("max_pdrop", 1e6)); std::vector<double> pdrops; pdrops.resize(num_pdrops); for (int i = 0; i < num_pdrops; ++i) { double factor = num_pdrops == 1 ? 0 : double(i)/double(num_pdrops - 1); pdrops[i] = std::exp((1.0 - factor)*log_min_pdrop + factor*log_max_pdrop); } // Assign the same pressure drops to all saturations. for (int i = 0; i < num_sats; ++i) { all_pdrops.appendRow(pdrops.begin(), pdrops.end()); } } int flow_direction = param.getDefault("flow_direction", 0); // Print the saturations and pressure drops. // writeControl(std::cout, saturations, all_pdrops); // Initialize upscaler. typedef SteadyStateUpscaler<Traits> Upscaler; typedef typename Upscaler::permtensor_t permtensor_t; Upscaler upscaler; upscaler.init(param); // First, compute an upscaled permeability. permtensor_t upscaled_K = upscaler.upscaleSinglePhase(); permtensor_t upscaled_K_copy = upscaled_K; upscaled_K_copy *= (1.0/(Opm::prefix::milli*Opm::unit::darcy)); std::cout.precision(15); std::cout << "Upscaled K in millidarcy:\n" << upscaled_K_copy << std::endl; std::cout << "Upscaled porosity: " << upscaler.upscalePorosity() << std::endl; // Create output streams for upscaled relative permeabilities std::string kr_filename = param.getDefault<std::string>("kr_filename", "upscaled_relperm"); std::string krw_filename = kr_filename + "_water"; std::string kro_filename = kr_filename + "_oil"; std::ofstream krw_out(krw_filename.c_str()); std::ofstream kro_out(kro_filename.c_str()); krw_out << "# Result from steady state upscaling" << std::endl; krw_out << "# Pressuredrop Sw Krxx Kryy Krzz" << std::endl; kro_out << "# Result from steady state upscaling" << std::endl; kro_out << "# Pressuredrop Sw Krxx Kryy Krzz" << std::endl; krw_out.precision(15); krw_out.setf(std::ios::scientific | std::ios::showpoint); kro_out.precision(15); kro_out.setf(std::ios::scientific | std::ios::showpoint); //#endif // Then, compute some upscaled relative permeabilities. int num_cells = upscaler.grid().size(0); int num_sats = saturations.size(); for (int i = 0; i < num_sats; ++i) { // Starting every computation with a trio of uniform profiles. std::vector<double> init_sat(num_cells, saturations[i]); const Opm::SparseTable<double>::row_type pdrops = all_pdrops[i]; int num_pdrops = pdrops.size(); for (int j = 0; j < num_pdrops; ++j) { double pdrop = pdrops[j]; std::pair<permtensor_t, permtensor_t> lambda = upscaler.upscaleSteadyState(flow_direction, init_sat, saturations[i], pdrop, upscaled_K); double usat = upscaler.lastSaturationUpscaled(); std::cout << "\n\nTensor of upscaled relperms for initial saturation " << saturations[i] << ", real steady-state saturation " << usat << " and pressure drop " << pdrop << ":\n\n[water]\n" << lambda.first << "\n[oil]\n" << lambda.second << std::endl; // Changing initial saturations for next pressure drop to equal the steady state of the last init_sat = upscaler.lastSaturationState(); writeRelPerm(krw_out, lambda.first , usat, pdrop); writeRelPerm(kro_out, lambda.second, usat, pdrop); } } }