コード例 #1
0
EquelleRuntimeCPU::EquelleRuntimeCPU(const Opm::parameter::ParameterGroup& param)
    : grid_manager_(createGridManager(param)),
      grid_(*(grid_manager_->c_grid())),
      ops_(grid_),
      linsolver_(param),
      output_to_file_(param.getDefault("output_to_file", false)),
      verbose_(param.getDefault("verbose", 0)),
      param_(param),
      max_iter_(param.getDefault("max_iter", 10)),
      abs_res_tol_(param.getDefault("abs_res_tol", 1e-6))
{
}
コード例 #2
0
    virtual void initSources(const Opm::parameter::ParameterGroup& param)
    {
        // Zero-initializing first.
        int nc = this->ginterf_.numberOfCells();
        this->injection_rates_ = Opm::SparseVector<double>(nc);
        this->injection_rates_psolver_.resize(nc, 0.0);

//             this->injection_rates_.addElement(1.0, 0);
//             this->injection_rates_psolver_[0] = 1.0;
//             this->injection_rates_.addElement(-1.0, nc-1);
//             this->injection_rates_psolver_[nc-1] = -1.0;

        // Initializing blocks.
        double total_inj = 0.0;
        bool has_inj_block = param.getDefault("has_inj_block", false);
        if (has_inj_block) {
            Vector low;
            low[0] = param.getDefault("inj_block_low_x", 0.0);
            low[1] = param.getDefault("inj_block_low_y", 0.0);
            low[2] = param.getDefault("inj_block_low_z", 0.0);
            Vector high;
            high[0] = param.getDefault("inj_block_high_x", 1.0);
            high[1] = param.getDefault("inj_block_high_y", 1.0);
            high[2] = param.getDefault("inj_block_high_z", 1.0);
            double inj_block_density = param.get<double>("inj_block_density");
            total_inj = setSourceBlock(low, high, inj_block_density, true);
        }
        double total_prod = 0.0;
        bool has_prod_block = param.getDefault("has_prod_block", false);
        if (has_prod_block) {
            Vector low;
            low[0] = param.getDefault("prod_block_low_x", 0.0);
            low[1] = param.getDefault("prod_block_low_y", 0.0);
            low[2] = param.getDefault("prod_block_low_z", 0.0);
            Vector high;
            high[0] = param.getDefault("prod_block_high_x", 1.0);
            high[1] = param.getDefault("prod_block_high_y", 1.0);
            high[2] = param.getDefault("prod_block_high_z", 1.0);
            double prod_block_density = param.get<double>("prod_block_density");
            total_prod = setSourceBlock(low, high, prod_block_density, false);
        }
        if (has_inj_block || has_prod_block) {
            std::cout << "Initialized injectors with total rate: " << total_inj
                      << "\nInitialized producers with total rate: " << total_prod
                      << std::endl;
        }
    }
コード例 #3
0
ファイル: setupGridAndProps.hpp プロジェクト: hnil/opm-porsol
    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);
	}
    }
コード例 #4
0
    inline void setupRegionBasedConditions(const Opm::parameter::ParameterGroup& param,
                                           const GridInterface& g,
                                           BCs& bcs)
    {
        // Extract region and pressure value for Dirichlet bcs.
        typedef typename GridInterface::Vector Vector;
        Vector low;
        low[0] = param.getDefault("dir_block_low_x", 0.0);
        low[1] = param.getDefault("dir_block_low_y", 0.0);
        low[2] = param.getDefault("dir_block_low_z", 0.0);
        Vector high;
        high[0] = param.getDefault("dir_block_high_x", 1.0);
        high[1] = param.getDefault("dir_block_high_y", 1.0);
        high[2] = param.getDefault("dir_block_high_z", 1.0);
        double dir_block_pressure = param.get<double>("dir_block_pressure");

        // Set flow conditions for that region.
        // For this to work correctly, unique boundary ids should be used,
        // otherwise conditions may spread outside the given region, to all
        // faces with the same bid as faces inside the region.
        typedef typename GridInterface::CellIterator CI;
        typedef typename CI::FaceIterator FI;
        int max_bid = 0;
        std::vector<int> dir_bids;
        for (CI c = g.cellbegin(); c != g.cellend(); ++c) {
            for (FI f = c->facebegin(); f != c->faceend(); ++f) {
                int bid = f->boundaryId();
                max_bid = std::max(bid, max_bid);
                if (bid != 0 && isInside(low, high, f->centroid())) {
                    dir_bids.push_back(bid);
                }
            }
        }
        bcs.resize(max_bid + 1);
        for (std::vector<int>::const_iterator it = dir_bids.begin(); it != dir_bids.end(); ++it) {
            bcs.flowCond(*it) = FlowBC(FlowBC::Dirichlet, dir_block_pressure);
        }

        // Transport BCs are defaulted.
    }
コード例 #5
0
 inline void EulerUpstreamImplicit<GI, RP, BC>::init(const Opm::parameter::ParameterGroup& param)
 {
     check_sat_ = param.getDefault("check_sat", check_sat_);
     clamp_sat_ = param.getDefault("clamp_sat", clamp_sat_);
     //Opm::ImplicitTransportDetails::NRControl ctrl_;
     ctrl_.max_it = param.getDefault("transport_nr_max_it", 10);
     max_repeats_ = param.getDefault("transport_max_rep", 10);
     ctrl_.atol  = param.getDefault("transport_atol", 1.0e-6);
     ctrl_.rtol  = param.getDefault("transport_rtol", 5.0e-7);
     ctrl_.max_it_ls = param.getDefault("transport_max_it_ls", 20);
     ctrl_.dxtol = param.getDefault("transport_dxtol", 1e-6);
     ctrl_.verbosity = param.getDefault("transport_verbosity", 0);
 }
コード例 #6
0
ファイル: setupGridAndProps.hpp プロジェクト: OPM/opm-porsol
 inline void setupGridAndProps(const Opm::parameter::ParameterGroup& param,
                               Dune::SGrid<3, 3>& 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 == "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.~SGrid<3,3>();
         new (&grid) Dune::SGrid<3, 3>(&dims[0], &cellsz[0]);
         double default_poro = param.getDefault("default_poro", 0.2);
         double default_perm = param.getDefault("default_perm", 100.0*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, "Dune::SGrid can only handle cartesian grids, unsupported file format string: " << fileformat);
     }
 }
コード例 #7
0
ファイル: EulerUpstream_impl.hpp プロジェクト: OPM/opm-porsol
    inline void EulerUpstream<GI, RP, BC>::init(const Opm::parameter::ParameterGroup& param)
    {
	courant_number_ = param.getDefault("courant_number", courant_number_);
	method_viscous_ = param.getDefault("method_viscous", method_viscous_);
	method_gravity_ = param.getDefault("method_gravity", method_gravity_);
	method_capillary_ = param.getDefault("method_capillary", method_capillary_);
	use_cfl_viscous_ = param.getDefault("use_cfl_viscous", use_cfl_viscous_);
	use_cfl_gravity_ = param.getDefault("use_cfl_gravity", use_cfl_gravity_);
	use_cfl_capillary_ = param.getDefault("use_cfl_capillary", use_cfl_capillary_);
	minimum_small_steps_ = param.getDefault("minimum_small_steps", minimum_small_steps_);
	maximum_small_steps_ = param.getDefault("maximum_small_steps", maximum_small_steps_);
	check_sat_ = param.getDefault("check_sat", check_sat_);
	clamp_sat_ = param.getDefault("clamp_sat", clamp_sat_);
    }
コード例 #8
0
 void LinearSolverISTL::init(const Opm::parameter::ParameterGroup& param)
 {
     linsolver_residual_tolerance_ = param.getDefault("linsolver_residual_tolerance", linsolver_residual_tolerance_);
     linsolver_verbosity_ = param.getDefault("linsolver_verbosity", linsolver_verbosity_);
     linsolver_type_ = LinsolverType(param.getDefault("linsolver_type", int(linsolver_type_)));
     linsolver_save_system_ = param.getDefault("linsolver_save_system", linsolver_save_system_);
     if (linsolver_save_system_) {
         linsolver_save_filename_ = param.getDefault("linsolver_save_filename", std::string("linsys"));
     }
     linsolver_max_iterations_ = param.getDefault("linsolver_max_iterations", linsolver_max_iterations_);
 }
コード例 #9
0
    inline void ImplicitCapillarity<GI, RP, BC, IP>::init(const Opm::parameter::ParameterGroup& param)
    {
	method_viscous_ = param.getDefault("method_viscous", method_viscous_);
	method_gravity_ = param.getDefault("method_gravity", method_gravity_);
	check_sat_ = param.getDefault("check_sat", check_sat_);
	clamp_sat_ = param.getDefault("clamp_sat", clamp_sat_);
	residual_tolerance_ = param.getDefault("residual_tolerance", residual_tolerance_);
	linsolver_verbosity_ = param.getDefault("linsolver_verbosity", linsolver_verbosity_);
	linsolver_type_ = param.getDefault("linsolver_type", linsolver_type_);
        update_relaxation_ = param.getDefault("update_relaxation", update_relaxation_);
    }
コード例 #10
0
    inline void UpscalerBase<Traits>::initImpl(const Opm::parameter::ParameterGroup& param)
    {
        // Request the boundary condition type parameter early since,
        // depending on the actual type, we may have to manufacture
        // and insert other parameters into the ParameterGroup prior
        // to constructing the grid and associated properties.
        //
        int bct = param.get<int>("boundary_condition_type");
	bctype_ = static_cast<BoundaryConditionType>(bct);

        // Import control parameters pertaining to reduced physical
        // dimensionality ("2d_hack = true" precludes periodic
        // boundary conditions in the Z direction), and linear solves.
        //
        twodim_hack_ = param.getDefault("2d_hack", twodim_hack_);
	residual_tolerance_ = param.getDefault("residual_tolerance", residual_tolerance_);
	linsolver_verbosity_ = param.getDefault("linsolver_verbosity", linsolver_verbosity_);
        linsolver_type_ = param.getDefault("linsolver_type", linsolver_type_);
        linsolver_maxit_ = param.getDefault("linsolver_max_iterations", linsolver_maxit_);
        linsolver_prolongate_factor_ = param.getDefault("linsolver_prolongate_factor", linsolver_prolongate_factor_);
        linsolver_smooth_steps_ = param.getDefault("linsolver_smooth_steps", linsolver_smooth_steps_);

        // Ensure sufficient grid support for requested boundary
        // condition type.
        //
	Opm::parameter::ParameterGroup temp_param = param;
        if (bctype_ == Linear || bctype_ == Periodic) {
            if (!temp_param.has("use_unique_boundary_ids")) {
                temp_param.insertParameter("use_unique_boundary_ids", "true");
            }
        }
        if (bctype_ == Periodic) {
            if (!temp_param.has("periodic_extension")) {
                temp_param.insertParameter("periodic_extension", "true");
            }
        }

	setupGridAndProps(temp_param, grid_, res_prop_);
	ginterf_.init(grid_);
    }
コード例 #11
0
    inline void setupBoundaryConditions(const Opm::parameter::ParameterGroup& param,
					const GridInterface& g,
					BCs& bcs)
    {
	if (param.getDefault("upscaling", false)) {
	    int bct = param.get<int>("boundary_condition_type");
	    int pddir = param.getDefault("pressure_drop_direction", 0);
	    double pdrop = param.getDefault("boundary_pressuredrop", 1.0e5);
	    double bdy_sat = param.getDefault("boundary_saturation", 1.0);
	    bool twodim_hack = param.getDefault("2d_hack", false);
	    setupUpscalingConditions(g, bct, pddir, pdrop, bdy_sat, twodim_hack, bcs);
	    return;
	}
        if (param.getDefault("region_based_bcs", false)) {
            setupRegionBasedConditions(param, g, bcs);
            return;
        }
	// Make flow equation boundary conditions.
	// Default is pressure 1.0e5 on the left, 0.0 on the right.
	// Recall that the boundary ids range from 1 to 6 for the cartesian edges,
	// and that boundary id 0 means interiour face/intersection.
	std::string flow_bc_type = param.getDefault<std::string>("flow_bc_type", "dirichlet");
	FlowBC::BCType bct = FlowBC::Dirichlet;
	double leftval = 1.0*Opm::unit::barsa;
	double rightval = 0.0;
	if (flow_bc_type == "neumann") {
	    bct = FlowBC::Neumann;
	    leftval = param.get<double>("left_flux");
	    rightval = param.getDefault<double>("right_flux", -leftval);
	} else if (flow_bc_type == "dirichlet") {
	    leftval = param.getDefault<double>("left_pressure", leftval);
	    rightval = param.getDefault<double>("right_pressure", rightval);
	} else if (flow_bc_type == "periodic") {
	    THROW("Periodic conditions not here yet.");
	} else {
	    THROW("Unknown flow boundary condition type " << flow_bc_type);
	}
	bcs.resize(7);
	bcs.flowCond(1) = FlowBC(bct, leftval);
	bcs.flowCond(2) = FlowBC(bct, rightval);

	// Default transport boundary conditions are used.
    }
コード例 #12
0
ファイル: setupGridAndProps.hpp プロジェクト: OPM/opm-porsol
    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);
        }
    }
コード例 #13
0
inline void SteadyStateUpscaler<Traits>::initImpl(const Opm::parameter::ParameterGroup& param)
{
    Super::initImpl(param);
    use_gravity_ =  param.getDefault("use_gravity", use_gravity_);
    output_vtk_ = param.getDefault("output_vtk", output_vtk_);
    print_inoutflows_ = param.getDefault("print_inoutflows", print_inoutflows_);
    simulation_steps_ = param.getDefault("simulation_steps", simulation_steps_);
    stepsize_ = Opm::unit::convert::from(param.getDefault("stepsize", stepsize_),
                                         Opm::unit::day);
    relperm_threshold_ = param.getDefault("relperm_threshold", relperm_threshold_);
    maximum_mobility_contrast_ = param.getDefault("maximum_mobility_contrast", maximum_mobility_contrast_);
    sat_change_threshold_ = param.getDefault("sat_change_threshold", sat_change_threshold_);

    transport_solver_.init(param);
    // Set viscosities and densities if given.
    double v1_default = this->res_prop_.viscosityFirstPhase();
    double v2_default = this->res_prop_.viscositySecondPhase();
    this->res_prop_.setViscosities(param.getDefault("viscosity1", v1_default), param.getDefault("viscosity2", v2_default));
    double d1_default = this->res_prop_.densityFirstPhase();
    double d2_default = this->res_prop_.densitySecondPhase();
    this->res_prop_.setDensities(param.getDefault("density1", d1_default), param.getDefault("density2", d2_default));
}
コード例 #14
0
        virtual void init(const Opm::parameter::ParameterGroup& param,
                          const Grid& grid,
                          const Fluid& fluid,
                          typename Grid::Vector gravity,
                          State& simstate)
        {
            typedef typename Fluid::CompVec CompVec;
            typedef typename Fluid::PhaseVec PhaseVec;

            if (param.getDefault("heterogenous_initial_mix", false)) {
                CompVec init_oil(0.0);
                init_oil[Fluid::Oil] = 1.0;
                CompVec init_water(0.0);
                init_water[Fluid::Water] = 1.0;
                simstate.cell_z_.resize(grid.numCells());
                std::fill(simstate.cell_z_.begin(), simstate.cell_z_.begin() + simstate.cell_z_.size()/2, init_oil);
                std::fill(simstate.cell_z_.begin() + simstate.cell_z_.size()/2, simstate.cell_z_.end(), init_water);
                OPM_MESSAGE("******* Assuming zero capillary pressures *******");
                PhaseVec init_p(100.0*Opm::unit::barsa);
                simstate.cell_pressure_.resize(grid.numCells(), init_p);
                //         if (gravity.two_norm() != 0.0) {
                //             double ref_gravpot = grid.cellCentroid(0)*gravity;
                //             double rho = init_z*fluid_.surfaceDensities();  // Assuming incompressible, and constant initial z.
                //             for (int cell = 1; cell < grid.numCells(); ++cell) {
                //                 double press = rho*(grid.cellCentroid(cell)*gravity - ref_gravpot) + simstate.cell_pressure_[0][0];
                //                 simstate.cell_pressure_[cell] = PhaseVec(press);
                //             }
                //         }
            } else if (param.getDefault("unstable_initial_mix", false)) {
                CompVec init_oil(0.0);
                init_oil[Fluid::Oil] = 1.0;
                init_oil[Fluid::Gas] = 0.0;
                CompVec init_water(0.0);
                init_water[Fluid::Water] = 1.0;
                CompVec init_gas(0.0);
                init_gas[Fluid::Gas] = 150.0;
                simstate.cell_z_.resize(grid.numCells());
                std::fill(simstate.cell_z_.begin(),
                          simstate.cell_z_.begin() + simstate.cell_z_.size()/3,
                          init_water);
                std::fill(simstate.cell_z_.begin() + simstate.cell_z_.size()/3,
                          simstate.cell_z_.begin() + 2*(simstate.cell_z_.size()/3),
                          init_oil);
                std::fill(simstate.cell_z_.begin() + 2*(simstate.cell_z_.size()/3),
                          simstate.cell_z_.end(),
                          init_gas);
                OPM_MESSAGE("******* Assuming zero capillary pressures *******");
                PhaseVec init_p(100.0*Opm::unit::barsa);
                simstate.cell_pressure_.resize(grid.numCells(), init_p);

                if (gravity.two_norm() != 0.0) {
            
                    typename Fluid::FluidState state = fluid.computeState(simstate.cell_pressure_[0], simstate.cell_z_[0]);
                    simstate.cell_z_[0] *= 1.0/state.total_phase_volume_density_;
                    for (int cell = 1; cell < grid.numCells(); ++cell) {
                        double fluid_vol_dens;
                        int cnt =0;    
                        do {
                            double rho = 0.5*((simstate.cell_z_[cell]+simstate.cell_z_[cell-1])*fluid.surfaceDensities());
                            double press = rho*((grid.cellCentroid(cell) - grid.cellCentroid(cell-1))*gravity) + simstate.cell_pressure_[cell-1][0];
                            simstate.cell_pressure_[cell] = PhaseVec(press);
                            state = fluid.computeState(simstate.cell_pressure_[cell], simstate.cell_z_[cell]);
                            fluid_vol_dens = state.total_phase_volume_density_;
                            simstate.cell_z_[cell] *= 1.0/fluid_vol_dens;
                            ++cnt;
                        } while (std::fabs((fluid_vol_dens-1.0)) > 1.0e-8 && cnt < 10);
                
                    }  
                } else {
                    std::cout << "---- Exit - BlackoilSimulator.hpp: No gravity, no fun ... ----" << std::endl;
                    exit(-1);
                } 
            } else if (param.getDefault("CO2-injection", false)) {
                CompVec init_water(0.0);
                // Initially water filled (use Oil-component for water in order
                // to utilise blackoil mechanisms for brine-co2 interaction)          
                init_water[Fluid::Oil] = 1.0;  
                simstate.cell_z_.resize(grid.numCells());
                std::fill(simstate.cell_z_.begin(),simstate.cell_z_.end(),init_water);

                double datum_pressure_barsa = param.getDefault<double>("datum_pressure", 200.0);
                double datum_pressure = Opm::unit::convert::from(datum_pressure_barsa, Opm::unit::barsa);
                PhaseVec init_p(datum_pressure);
                simstate.cell_pressure_.resize(grid.numCells(), init_p);

                // Simple initial condition based on "incompressibility"-assumption
                double zMin = grid.cellCentroid(0)[2];
                for (int cell = 1; cell < grid.numCells(); ++cell) {
                    if (grid.cellCentroid(cell)[2] < zMin)
                        zMin = grid.cellCentroid(cell)[2];
                }

                typename Fluid::FluidState state = fluid.computeState(init_p, init_water);
		simstate.cell_z_[0] *= 1.0/state.total_phase_volume_density_;
                double density = (init_water*fluid.surfaceDensities())/state.total_phase_volume_density_;

                for (int cell = 0; cell < grid.numCells(); ++cell) {
                    double pressure(datum_pressure + (grid.cellCentroid(cell)[2] - zMin)*gravity[2]*density);
                    simstate.cell_pressure_[cell] = PhaseVec(pressure);
                    state = fluid.computeState(simstate.cell_pressure_[cell], simstate.cell_z_[cell]);
                    simstate.cell_z_[cell] *= 1.0/state.total_phase_volume_density_;
                }       
            } else {
                CompVec init_z(0.0);
                double initial_mixture_gas = param.getDefault("initial_mixture_gas", 0.0);
                double initial_mixture_oil = param.getDefault("initial_mixture_oil", 1.0);
                double initial_mixture_water = param.getDefault("initial_mixture_water", 0.0);
                init_z[Fluid::Water] = initial_mixture_water;
                init_z[Fluid::Gas] = initial_mixture_gas;
                init_z[Fluid::Oil] = initial_mixture_oil;

                simstate.cell_z_.resize(grid.numCells(), init_z);
                OPM_MESSAGE("******* Assuming zero capillary pressures *******");
                PhaseVec init_p(param.getDefault("initial_pressure", 100.0*Opm::unit::barsa));
                simstate.cell_pressure_.resize(grid.numCells(), init_p);
                if (gravity.two_norm() != 0.0) {
                    double ref_gravpot = grid.cellCentroid(0)*gravity;
                    double rho = init_z*fluid.surfaceDensities();  // Assuming incompressible, and constant initial z.
                    for (int cell = 1; cell < grid.numCells(); ++cell) {
                        double press = rho*(grid.cellCentroid(cell)*gravity - ref_gravpot) + simstate.cell_pressure_[0][0];
                        simstate.cell_pressure_[cell] = PhaseVec(press);
                    }
                }
            }
        }
コード例 #15
0
        virtual void init(const Opm::parameter::ParameterGroup& param,
                          const Grid& grid,
                          const Fluid& fluid,
                          typename Grid::Vector gravity,
                          State& simstate)
        {
            typedef typename Fluid::CompVec CompVec;

            double zeroDepth = param.getDefault("zero_depth", 2743.2);
            int nx = param.getDefault<int>("nx", 24);
            int ny = param.getDefault<int>("ny", 25);
            int nz = param.getDefault<int>("nz", 15);
        
            // double datum_depth = param.getDefault<double>("datum_depth", 2753.87) - zeroDepth;
            double datum_pressure_barsa = param.getDefault<double>("datum_pressure", 248.22);
            double datum_pressure = Opm::unit::convert::from(datum_pressure_barsa, Opm::unit::barsa);
            double wo_contact_depth = param.getDefault<double>("wo_contact_depth", 3032.76) - zeroDepth;
            double go_contact_depth = param.getDefault<double>("go_contact_depth", 2682.24) - zeroDepth;
        
            double connate_water_saturation = param.getDefault<double>("connate_water_saturation", 0.151090);
            double residual_oil_saturation = param.getDefault<double>("residual_oil_saturation", 0.118510);
        
            double initial_mixture_gas = param.getDefault("initial_mixture_gas", 247.43);
            double initial_mixture_oil = param.getDefault("initial_mixture_oil", 1.0);

            // Initial fluid state
            CompVec oil_sample(0.0);
            oil_sample[Fluid::Oil] = initial_mixture_oil;
            oil_sample[Fluid::Gas] = initial_mixture_gas;
            CompVec water_sample(0.0); 
            water_sample[Fluid::Water] = 1.0;
        
            simstate.cell_z_.resize(grid.numCells());
            simstate.cell_pressure_.resize(grid.numCells());
        
            // Datum -cell
            // For now, assume that datum_depth corresponds the centroid of cell 0 (reasonable approx)
            simstate.cell_pressure_[0] = datum_pressure;    
            typename Fluid::FluidState state = fluid.computeState(simstate.cell_pressure_[0],oil_sample);
            simstate.cell_z_[0] = oil_sample;
            simstate.cell_z_[0] *= (1.0-connate_water_saturation)/state.total_phase_volume_density_;
            state = fluid.computeState(simstate.cell_pressure_[0],water_sample);
            simstate.cell_z_[0][Fluid::Water] = water_sample[Fluid::Water];
            simstate.cell_z_[0][Fluid::Water] *= connate_water_saturation/state.total_phase_volume_density_;
            // Rest of the cells -- NOTE: Assume uniform cell properties in y-direction
            for (int i=0; i<nx; ++i) {
                int k0=i*nz; 
                for (int k=0; k<nz; ++k) {
                    int kk=k0+k;
                    if (i>0 && k==0) {
                        computeCellState(grid, fluid, gravity,
                                         kk, kk-nz, wo_contact_depth, go_contact_depth, connate_water_saturation,
                                         residual_oil_saturation, simstate);
                    } else if (k>0) { 
                        computeCellState(grid, fluid, gravity,
                                         kk, kk-1, wo_contact_depth, go_contact_depth, connate_water_saturation,
                                         residual_oil_saturation, simstate);
                    }
                    // Copy cell properties to y-layers
                    for (int j=1; j<ny; ++j) {
                        int jj = j*nx*nz + kk;
                        simstate.cell_z_[jj] = simstate.cell_z_[kk];
                        simstate.cell_pressure_[jj] = simstate.cell_pressure_[kk];
                    }
                }                
            }
        }
コード例 #16
0
        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);
		    
                }
            }
        }