Beispiel #1
0
    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);
	}
    }
Beispiel #2
0
 /// 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);
     }
 }
Beispiel #3
0
    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);
		    
                }
            }
        }