コード例 #1
0
        void readFromDeck(const EclipseGridParser& gridparser)
        {

            // We assume NTMISC=1
            const std::vector<double>& plymax = gridparser.getPLYMAX().plymax_;
            c_max_ = plymax[0];
            const std::vector<double>& tlmixpar = gridparser.getTLMIXPAR().tlmixpar_;
            mix_param_ = tlmixpar[0];

            // We assume NTSFUN=1
            const std::vector<double>& plyrock = gridparser.getPLYROCK().plyrock_;
            assert(plyrock.size() == 5);
            dead_pore_vol_ = plyrock[0];
            res_factor_ = plyrock[1];
            rock_density_ = plyrock[2];
            ads_index_ = static_cast<AdsorptionBehaviour>(plyrock[3]);
            c_max_ads_ = plyrock[4];

            // We assume NTPVT=1
            const PLYVISC& plyvisc = gridparser.getPLYVISC();
            c_vals_visc_ = plyvisc.concentration_;
            visc_mult_vals_ = plyvisc.factor_;

            // We assume NTSFUN=1
            const PLYADS& plyads = gridparser.getPLYADS();
            c_vals_ads_ = plyads.local_concentration_;
            ads_vals_ = plyads.adsorbed_concentration_;

        }
コード例 #2
0
    void SaturationPropsFromDeck<SatFuncSet>::init(const EclipseGridParser& deck,
                                                   const UnstructuredGrid& grid,
                                                   const int samples)
    {
        phase_usage_ = phaseUsageFromDeck(deck);

        // Extract input data.
        // Oil phase should be active.
        if (!phase_usage_.phase_used[Liquid]) {
            THROW("SaturationPropsFromDeck::init()   --  oil phase must be active.");
        }

        // Obtain SATNUM, if it exists, and create cell_to_func_.
        // Otherwise, let the cell_to_func_ mapping be just empty.
        int satfuncs_expected = 1;
        if (deck.hasField("SATNUM")) {
            const std::vector<int>& satnum = deck.getIntegerValue("SATNUM");
            satfuncs_expected = *std::max_element(satnum.begin(), satnum.end());
            const int num_cells = grid.number_of_cells;
            cell_to_func_.resize(num_cells);
            const int* gc = grid.global_cell;
            for (int cell = 0; cell < num_cells; ++cell) {
                const int deck_pos = (gc == NULL) ? cell : gc[cell];
                cell_to_func_[cell] = satnum[deck_pos] - 1;
            }
        }

        // Find number of tables, check for consistency.
        enum { Uninitialized = -1 };
        int num_tables = Uninitialized;
        if (phase_usage_.phase_used[Aqua]) {
            const SWOF::table_t& swof_table = deck.getSWOF().swof_;
            num_tables = swof_table.size();
            if (num_tables < satfuncs_expected) {
                THROW("Found " << num_tables << " SWOF tables, SATNUM specifies at least " << satfuncs_expected);
            }
        }
        if (phase_usage_.phase_used[Vapour]) {
            const SGOF::table_t& sgof_table = deck.getSGOF().sgof_;
            int num_sgof_tables = sgof_table.size();
            if (num_sgof_tables < satfuncs_expected) {
                THROW("Found " << num_tables << " SGOF tables, SATNUM specifies at least " << satfuncs_expected);
            }
            if (num_tables == Uninitialized) {
                num_tables = num_sgof_tables;
            } else if (num_tables != num_sgof_tables) {
                THROW("Inconsistent number of tables in SWOF and SGOF.");
            }
        }

        // Initialize tables.
        satfuncset_.resize(num_tables);
        for (int table = 0; table < num_tables; ++table) {
            satfuncset_[table].init(deck, table, phase_usage_, samples);
        }
    }
コード例 #3
0
ファイル: initState_impl.hpp プロジェクト: 00liujj/opm-core
 void initBlackoilStateFromDeck(const UnstructuredGrid& grid,
                                const Props& props,
                                const EclipseGridParser& deck,
                                const double gravity,
                                State& state)
 {
     initStateFromDeck(grid, props, deck, gravity, state);
     initBlackoilSurfvol(grid, props, state);
     if (deck.hasField("RS")) {
         const std::vector<double>& rs_deck = deck.getFloatingPointValue("RS");
         const int num_cells = grid.number_of_cells;
         for (int c = 0; c < num_cells; ++c) {
             int c_deck = (grid.global_cell == NULL) ? c : grid.global_cell[c];
             state.gasoilratio()[c] = rs_deck[c_deck];
         }
     } else {
         THROW("Temporarily, we require the RS field.");
     }
 }
コード例 #4
0
ファイル: SatFuncGwseg.cpp プロジェクト: dhbernstein/opm-core
 void SatFuncGwsegUniform::init(const EclipseGridParser& deck,
                                const int table_num,
                                const PhaseUsage phase_usg,
                                const int samples)
 {
     phase_usage = phase_usg;
     double swco = 0.0;
     double swmax = 1.0;
     if (phase_usage.phase_used[Aqua]) {
         const SWOF::table_t& swof_table = deck.getSWOF().swof_;
         const std::vector<double>& sw = swof_table[table_num][0];
         const std::vector<double>& krw = swof_table[table_num][1];
         const std::vector<double>& krow = swof_table[table_num][2];
         const std::vector<double>& pcow = swof_table[table_num][3];
         buildUniformMonotoneTable(sw, krw,  samples, krw_);
         buildUniformMonotoneTable(sw, krow, samples, krow_);
         buildUniformMonotoneTable(sw, pcow, samples, pcow_);
         krocw_ = krow[0]; // At connate water -> ecl. SWOF
         swco = sw[0];
         smin_[phase_usage.phase_pos[Aqua]] = sw[0];
         swmax = sw.back();
         smax_[phase_usage.phase_pos[Aqua]] = sw.back();
     }
     if (phase_usage.phase_used[Vapour]) {
         const SGOF::table_t& sgof_table = deck.getSGOF().sgof_;
         const std::vector<double>& sg = sgof_table[table_num][0];
         const std::vector<double>& krg = sgof_table[table_num][1];
         const std::vector<double>& krog = sgof_table[table_num][2];
         const std::vector<double>& pcog = sgof_table[table_num][3];
         buildUniformMonotoneTable(sg, krg,  samples, krg_);
         buildUniformMonotoneTable(sg, krog, samples, krog_);
         buildUniformMonotoneTable(sg, pcog, samples, pcog_);
         smin_[phase_usage.phase_pos[Vapour]] = sg[0];
         if (std::fabs(sg.back() + swco - 1.0) > 1e-3) {
             THROW("Gas maximum saturation in SGOF table = " << sg.back() <<
                   ", should equal (1.0 - connate water sat) = " << (1.0 - swco));
         }
         smax_[phase_usage.phase_pos[Vapour]] = sg.back();
     }
     // These only consider water min/max sats. Consider gas sats?
     smin_[phase_usage.phase_pos[Liquid]] = 1.0 - swmax;
     smax_[phase_usage.phase_pos[Liquid]] = 1.0 - swco;
 }
コード例 #5
0
ファイル: RockCompressibility.cpp プロジェクト: hnil/opm-core
 RockCompressibility::RockCompressibility(const EclipseGridParser& deck)
     : pref_(0.0),
       rock_comp_(0.0)
 {
     if (deck.hasField("ROCKTAB")) {
         const table_t& rt = deck.getROCKTAB().rocktab_;
         int n = rt[0][0].size();
         p_.resize(n);
         poromult_.resize(n);
         for (int i = 0; i < n; ++i) {
             p_[i] = rt[0][0][i];
             poromult_[i] = rt[0][1][i];
         }
     } else if (deck.hasField("ROCK")) {
         const ROCK& r = deck.getROCK();
         pref_ = r.rock_compressibilities_[0][0];
         rock_comp_ = r.rock_compressibilities_[0][1];
     } else {
         std::cout << "**** warning: no rock compressibility data found in deck (ROCK or ROCKTAB)." << std::endl;
     }
 }
コード例 #6
0
ファイル: PolymerInflow.cpp プロジェクト: flikka/opm-polymer
    /// Constructor.
    /// @param[in]  deck     Input deck expected to contain WPOLYMER.
    PolymerInflowFromDeck::PolymerInflowFromDeck(const EclipseGridParser& deck,
                                                 const Wells& wells,
                                                 const int num_cells)
        : sparse_inflow_(num_cells)
    {
        if (!deck.hasField("WPOLYMER")) {
            OPM_MESSAGE("PolymerInflowFromDeck initialized without WPOLYMER in current epoch.");
            return;
        }

        // Extract concentrations and put into cell->concentration map.
        const std::vector<WpolymerLine>& wpl = deck.getWPOLYMER().wpolymer_;
        const int num_wpl = wpl.size();
        std::map<int, double> perfcell_conc;
        for (int i = 0; i < num_wpl; ++i) {
            // Only use well name and polymer concentration.
            // That is, we ignore salt concentration and group
            // names.
            int wix = 0;
            for (; wix < wells.number_of_wells; ++wix) {
                if (wpl[i].well_ == wells.name[wix]) {
                    break;
                }
            }
            if (wix == wells.number_of_wells) {
                OPM_THROW(std::runtime_error, "Could not find a match for well " << wpl[i].well_ << " from WPOLYMER.");
            }
            for (int j = wells.well_connpos[wix]; j < wells.well_connpos[wix+1]; ++j) {
                const int perf_cell = wells.well_cells[j];
                perfcell_conc[perf_cell] = wpl[i].polymer_concentration_;
            }
        }

        // Build sparse vector from map.
        std::map<int, double>::const_iterator it = perfcell_conc.begin();
        for (; it != perfcell_conc.end(); ++it) {
            sparse_inflow_.addElement(it->second, it->first);
        }
    }
コード例 #7
0
    void PvtPropertiesIncompFromDeck::init(const EclipseGridParser& deck)
    {
        typedef std::vector<std::vector<std::vector<double> > > table_t;
        // If we need multiple regions, this class and the SinglePvt* classes must change.
        int region_number = 0;

        PhaseUsage phase_usage = phaseUsageFromDeck(deck);
        if (phase_usage.phase_used[PhaseUsage::Vapour] ||
            !phase_usage.phase_used[PhaseUsage::Aqua] ||
            !phase_usage.phase_used[PhaseUsage::Liquid]) {
            THROW("PvtPropertiesIncompFromDeck::init() -- must have gas and oil phases (only) in deck input.\n");
        }

        // Surface densities. Accounting for different orders in eclipse and our code.
        if (deck.hasField("DENSITY")) {
            const std::vector<double>& d = deck.getDENSITY().densities_[region_number];
            enum { ECL_oil = 0, ECL_water = 1, ECL_gas = 2 };
            surface_density_[phase_usage.phase_pos[PhaseUsage::Aqua]]   = d[ECL_water];
            surface_density_[phase_usage.phase_pos[PhaseUsage::Liquid]] = d[ECL_oil];
        } else {
            THROW("Input is missing DENSITY\n");
        }

        // Make reservoir densities the same as surface densities initially.
        // We will modify them with formation volume factors if found.
        reservoir_density_ = surface_density_;

        // Water viscosity.
        if (deck.hasField("PVTW")) {
            const std::vector<double>& pvtw = deck.getPVTW().pvtw_[region_number];
            if (pvtw[2] != 0.0 || pvtw[4] != 0.0) {
                MESSAGE("Compressibility effects in PVTW are ignored.");
            }
            reservoir_density_[phase_usage.phase_pos[PhaseUsage::Aqua]] /= pvtw[1];
            viscosity_[phase_usage.phase_pos[PhaseUsage::Aqua]] = pvtw[3];
        } else {
            // Eclipse 100 default.
            // viscosity_[phase_usage.phase_pos[PhaseUsage::Aqua]] = 0.5*Opm::prefix::centi*Opm::unit::Poise;
            THROW("Input is missing PVTW\n");
        }

        // Oil viscosity.
        if (deck.hasField("PVCDO")) {
            const std::vector<double>& pvcdo = deck.getPVCDO().pvcdo_[region_number];
            if (pvcdo[2] != 0.0 || pvcdo[4] != 0.0) {
                MESSAGE("Compressibility effects in PVCDO are ignored.");
            }
            reservoir_density_[phase_usage.phase_pos[PhaseUsage::Liquid]] /= pvcdo[1];
            viscosity_[phase_usage.phase_pos[PhaseUsage::Liquid]] = pvcdo[3];
        } else {
            THROW("Input is missing PVCDO\n");
        }
    }
コード例 #8
0
ファイル: initState_impl.hpp プロジェクト: 00liujj/opm-core
    void initStateFromDeck(const UnstructuredGrid& grid,
                           const Props& props,
                           const EclipseGridParser& deck,
                           const double gravity,
                           State& state)
    {
        const int num_phases = props.numPhases();
        const PhaseUsage pu = phaseUsageFromDeck(deck);
        if (num_phases != pu.num_phases) {
            THROW("initStateFromDeck():  user specified property object with " << num_phases << " phases, "
                  "found " << pu.num_phases << " phases in deck.");
        }
        state.init(grid, num_phases);
        if (deck.hasField("EQUIL")) {
            if (num_phases != 2) {
                THROW("initStateFromDeck(): EQUIL-based init currently handling only two-phase scenarios.");
            }
            if (pu.phase_used[BlackoilPhases::Vapour]) {
                THROW("initStateFromDeck(): EQUIL-based init currently handling only oil-water scenario (no gas).");
            }
            // Set saturations depending on oil-water contact.
            const EQUIL& equil= deck.getEQUIL();
            if (equil.equil.size() != 1) {
                THROW("initStateFromDeck(): No region support yet.");
            }
            const double woc = equil.equil[0].water_oil_contact_depth_;
            initWaterOilContact(grid, props, woc, WaterBelow, state);
            // Set pressure depending on densities and depths.
            const double datum_z = equil.equil[0].datum_depth_;
            const double datum_p = equil.equil[0].datum_depth_pressure_;
            initHydrostaticPressure(grid, props, woc, gravity, datum_z, datum_p, state);
        } else if (deck.hasField("PRESSURE")) {
            // Set saturations from SWAT/SGAS, pressure from PRESSURE.
            std::vector<double>& s = state.saturation();
            std::vector<double>& p = state.pressure();
            const std::vector<double>& p_deck = deck.getFloatingPointValue("PRESSURE");
            const int num_cells = grid.number_of_cells;
            if (num_phases == 2) {
                if (!pu.phase_used[BlackoilPhases::Aqua]) {
                    // oil-gas: we require SGAS
                    if (!deck.hasField("SGAS")) {
                        THROW("initStateFromDeck(): missing SGAS keyword in 2-phase init");
                    }
                    const std::vector<double>& sg_deck = deck.getFloatingPointValue("SGAS");
                    const int gpos = pu.phase_pos[BlackoilPhases::Vapour];
                    const int opos = pu.phase_pos[BlackoilPhases::Liquid];
                    for (int c = 0; c < num_cells; ++c) {
                        int c_deck = (grid.global_cell == NULL) ? c : grid.global_cell[c];
                        s[2*c + gpos] = sg_deck[c_deck];
                        s[2*c + opos] = 1.0 - sg_deck[c_deck];
                        p[c] = p_deck[c_deck];
                    }
                } else {
                    // water-oil or water-gas: we require SWAT
                    if (!deck.hasField("SWAT")) {
                        THROW("initStateFromDeck(): missing SWAT keyword in 2-phase init");
                    }
                    const std::vector<double>& sw_deck = deck.getFloatingPointValue("SWAT");
                    const int wpos = pu.phase_pos[BlackoilPhases::Aqua];
                    const int nwpos = (wpos + 1) % 2;
                    for (int c = 0; c < num_cells; ++c) {
                        int c_deck = (grid.global_cell == NULL) ? c : grid.global_cell[c];
                        s[2*c + wpos] = sw_deck[c_deck];
                        s[2*c + nwpos] = 1.0 - sw_deck[c_deck];
                        p[c] = p_deck[c_deck];
                    }
                }
            } else if (num_phases == 3) {
                const bool has_swat_sgas = deck.hasField("SWAT") && deck.hasField("SGAS");
                if (!has_swat_sgas) {
                    THROW("initStateFromDeck(): missing SGAS or SWAT keyword in 3-phase init.");
                }
                const int wpos = pu.phase_pos[BlackoilPhases::Aqua];
                const int gpos = pu.phase_pos[BlackoilPhases::Vapour];
                const int opos = pu.phase_pos[BlackoilPhases::Liquid];
                const std::vector<double>& sw_deck = deck.getFloatingPointValue("SWAT");
                const std::vector<double>& sg_deck = deck.getFloatingPointValue("SGAS");
                for (int c = 0; c < num_cells; ++c) {
                    int c_deck = (grid.global_cell == NULL) ? c : grid.global_cell[c];
                    s[3*c + wpos] = sw_deck[c_deck];
                    s[3*c + opos] = 1.0 - (sw_deck[c_deck] + sg_deck[c_deck]);
                    s[3*c + gpos] = sg_deck[c_deck];
                    p[c] = p_deck[c_deck];
                 }
            } else {
                THROW("initStateFromDeck(): init with SWAT etc. only available with 2 or 3 phases.");
            }
        } else {
            THROW("initStateFromDeck(): we must either have EQUIL, or PRESSURE and SWAT/SOIL/SGAS.");
        }

        // Finally, init face pressures.
        initFacePressure(grid, state);
    }
コード例 #9
0
ファイル: SatFuncSimple.cpp プロジェクト: 00liujj/opm-core
    void SatFuncSimpleUniform::init(const EclipseGridParser& deck,
                             const int table_num,
                             const PhaseUsage phase_usg,
                             const int samples)
    {
        phase_usage = phase_usg;
        double swco = 0.0;
        double swmax = 1.0;
        if (phase_usage.phase_used[Aqua]) {
            const SWOF::table_t& swof_table = deck.getSWOF().swof_;
            const std::vector<double>& sw = swof_table[table_num][0];
            const std::vector<double>& krw = swof_table[table_num][1];
            const std::vector<double>& krow = swof_table[table_num][2];
            const std::vector<double>& pcow = swof_table[table_num][3];
            if (krw.front() != 0.0 || krow.back() != 0.0) {
                THROW("Error SWOF data - non-zero krw(swco) and/or krow(1-sor)");
            }
            buildUniformMonotoneTable(sw, krw,  samples, krw_);
            buildUniformMonotoneTable(sw, krow, samples, krow_);
            buildUniformMonotoneTable(sw, pcow, samples, pcow_);
            krocw_ = krow[0]; // At connate water -> ecl. SWOF
            swco = sw[0];
            smin_[phase_usage.phase_pos[Aqua]] = sw[0];
            swmax = sw.back();
            smax_[phase_usage.phase_pos[Aqua]] = sw.back();

            krwmax_ = krw.back();
            kromax_ = krow.front();
            swcr_ = swmax;
            sowcr_ = 1.0 - swco;
            krwr_ = krw.back();
            krorw_ = krow.front();
            for (std::vector<double>::size_type i=1; i<sw.size(); ++i) {
                if (krw[i]> 0.0) {
                   swcr_ = sw[i-1];
                   krorw_ = krow[i-1];
                   break;
                }
            }
            for (std::vector<double>::size_type i=sw.size()-1; i>=1; --i) {
                if (krow[i-1]> 0.0) {
                   sowcr_ = 1.0 - sw[i];
                   krwr_ = krw[i];
                   break;
                }
            }
        }
        if (phase_usage.phase_used[Vapour]) {
            const SGOF::table_t& sgof_table = deck.getSGOF().sgof_;
            const std::vector<double>& sg = sgof_table[table_num][0];
            const std::vector<double>& krg = sgof_table[table_num][1];
            const std::vector<double>& krog = sgof_table[table_num][2];
            const std::vector<double>& pcog = sgof_table[table_num][3];
            buildUniformMonotoneTable(sg, krg,  samples, krg_);
            buildUniformMonotoneTable(sg, krog, samples, krog_);
            buildUniformMonotoneTable(sg, pcog, samples, pcog_);
            smin_[phase_usage.phase_pos[Vapour]] = sg[0];
            if (std::fabs(sg.back() + swco - 1.0) > 1e-3) {
                THROW("Gas maximum saturation in SGOF table = " << sg.back() <<
                      ", should equal (1.0 - connate water sat) = " << (1.0 - swco));
            }
            smax_[phase_usage.phase_pos[Vapour]] = sg.back();
        }
        // These only consider water min/max sats. Consider gas sats?
        smin_[phase_usage.phase_pos[Liquid]] = 1.0 - swmax;
        smax_[phase_usage.phase_pos[Liquid]] = 1.0 - swco;
    }
コード例 #10
0
ファイル: SatFuncBase.hpp プロジェクト: karbor/opm-core
    void SatFuncBase<TableType>::init(const EclipseGridParser& deck,
                                      const int table_num,
                                      const PhaseUsage phase_usg,
                                      const int samples)
    {
        phase_usage = phase_usg;
        double swco = 0.0;
        double swmax = 1.0;
        if (phase_usage.phase_used[Aqua]) {
            const SWOF::table_t& swof_table = deck.getSWOF().swof_;
            const std::vector<double>& sw = swof_table[table_num][0];
            const std::vector<double>& krw = swof_table[table_num][1];
            const std::vector<double>& krow = swof_table[table_num][2];
            const std::vector<double>& pcow = swof_table[table_num][3];
            if (krw.front() != 0.0 || krow.back() != 0.0) {
                OPM_THROW(std::runtime_error, "Error SWOF data - non-zero krw(swco) and/or krow(1-sor)");
            }

            // Extend the tables with constant values such that the
            // derivatives at the endpoints are zero
            int n = sw.size();
            std::vector<double> sw_ex(n+2);
            std::vector<double> krw_ex(n+2);
            std::vector<double> krow_ex(n+2);
            std::vector<double> pcow_ex(n+2);

            extendTable(sw,sw_ex,1);
            extendTable(krw,krw_ex,0);
            extendTable(krow,krow_ex,0);
            extendTable(pcow,pcow_ex,0);

            initializeTableType(krw_,sw_ex, krw_ex, samples);
            initializeTableType(krow_,sw_ex, krow_ex, samples);
            initializeTableType(pcow_,sw_ex, pcow_ex, samples);

            krocw_ = krow[0]; // At connate water -> ecl. SWOF
            swco = sw[0];
            smin_[phase_usage.phase_pos[Aqua]] = sw[0];
            swmax = sw.back();
            smax_[phase_usage.phase_pos[Aqua]] = sw.back();

            krwmax_ = krw.back();
            kromax_ = krow.front();
            swcr_ = swmax;
            sowcr_ = 1.0 - swco;
            krwr_ = krw.back();
            krorw_ = krow.front();
            for (std::vector<double>::size_type i=1; i<sw.size(); ++i) {
                if (krw[i]> 0.0) {
                   swcr_ = sw[i-1];
                   krorw_ = krow[i-1];
                   break;
                }
            }
            for (std::vector<double>::size_type i=sw.size()-1; i>=1; --i) {
                if (krow[i-1]> 0.0) {
                   sowcr_ = 1.0 - sw[i];
                   krwr_ = krw[i];
                   break;
                }
            }
        }
        if (phase_usage.phase_used[Vapour]) {
            const SGOF::table_t& sgof_table = deck.getSGOF().sgof_;
            const std::vector<double>& sg = sgof_table[table_num][0];
            const std::vector<double>& krg = sgof_table[table_num][1];
            const std::vector<double>& krog = sgof_table[table_num][2];
            const std::vector<double>& pcog = sgof_table[table_num][3];

            // Extend the tables with constant values such that the
            // derivatives at the endpoints are zero
            int n = sg.size();
            std::vector<double> sg_ex(n+2);
            std::vector<double> krg_ex(n+2);
            std::vector<double> krog_ex(n+2);
            std::vector<double> pcog_ex(n+2);

            extendTable(sg,sg_ex,1);
            extendTable(krg,krg_ex,0);
            extendTable(krog,krog_ex,0);
            extendTable(pcog,pcog_ex,0);

            initializeTableType(krg_,sg_ex, krg_ex, samples);
            initializeTableType(krog_,sg_ex, krog_ex, samples);
            initializeTableType(pcog_,sg_ex, pcog_ex, samples);

            smin_[phase_usage.phase_pos[Vapour]] = sg[0];
            if (std::fabs(sg.back() + swco - 1.0) > 1e-3) {
                OPM_THROW(std::runtime_error, "Gas maximum saturation in SGOF table = " << sg.back() <<
                      ", should equal (1.0 - connate water sat) = " << (1.0 - swco));
            }
            smax_[phase_usage.phase_pos[Vapour]] = sg.back();
            smin_[phase_usage.phase_pos[Vapour]] = sg.front();
            krgmax_ = krg.back();

            sgcr_ = sg.front();
            sogcr_ = 1.0 - sg.back();
            krgr_ = krg.back();
            krorg_ = krg.front();
            for (std::vector<double>::size_type i=1; i<sg.size(); ++i) {
                if (krg[i]> 0.0) {
                   sgcr_ = sg[i-1];
                   krorg_ = krog[i-1];
                   break;
                }
            }
            for (std::vector<double>::size_type i=sg.size()-1; i>=1; --i) {
                if (krog[i-1]> 0.0) {
                   sogcr_ = 1.0 - sg[i];
                   krgr_ = krg[i];
                   break;
                }
            }

        }

        if (phase_usage.phase_used[Vapour] && phase_usage.phase_used[Aqua]) {
            sowcr_ -= smin_[phase_usage.phase_pos[Vapour]];
            sogcr_ -= smin_[phase_usage.phase_pos[Aqua]];
            smin_[phase_usage.phase_pos[Liquid]] = 0.0;
            smax_[phase_usage.phase_pos[Liquid]] = 1.0 - smin_[phase_usage.phase_pos[Aqua]]
                                                       - smin_[phase_usage.phase_pos[Vapour]];  // First entry in SGOF-table supposed to be zero anyway ...
        } else if (phase_usage.phase_used[Aqua]) {
            smin_[phase_usage.phase_pos[Liquid]] = 1.0 - smax_[phase_usage.phase_pos[Aqua]];
            smax_[phase_usage.phase_pos[Liquid]] = 1.0 - smin_[phase_usage.phase_pos[Aqua]];
        } else if (phase_usage.phase_used[Vapour]) {
            smin_[phase_usage.phase_pos[Liquid]] = 1.0 - smax_[phase_usage.phase_pos[Vapour]];
            smax_[phase_usage.phase_pos[Liquid]] = 1.0 - smin_[phase_usage.phase_pos[Vapour]];
        }
    }
コード例 #11
0
ファイル: SimulatorTimer.cpp プロジェクト: hnil/opm-core
    /// Initialize from TSTEP field.
    void SimulatorTimer::init(const EclipseGridParser& deck)
    {
	timesteps_ = deck.getTSTEP().tstep_;
	total_time_ = std::accumulate(timesteps_.begin(), timesteps_.end(), 0.0);
    }
コード例 #12
0
    /// Constructor wrapping an opm-core black oil interface.
    BlackoilPropsAdFromDeck::BlackoilPropsAdFromDeck(const EclipseGridParser& deck,
                                                     const UnstructuredGrid& grid,
                                                     const bool init_rock)
    {
        if (init_rock){
            rock_.init(deck, grid);
        }
        const int samples = 0;
        const int region_number = 0;

        phase_usage_ = phaseUsageFromDeck(deck);

        // Surface densities. Accounting for different orders in eclipse and our code.
        if (deck.hasField("DENSITY")) {
            const std::vector<double>& d = deck.getDENSITY().densities_[region_number];
            enum { ECL_oil = 0, ECL_water = 1, ECL_gas = 2 };
            if (phase_usage_.phase_used[Aqua]) {
                densities_[phase_usage_.phase_pos[Aqua]]   = d[ECL_water];
            }
            if (phase_usage_.phase_used[Vapour]) {
                densities_[phase_usage_.phase_pos[Vapour]] = d[ECL_gas];
            }
            if (phase_usage_.phase_used[Liquid]) {
                densities_[phase_usage_.phase_pos[Liquid]] = d[ECL_oil];
            }
        } else {
            OPM_THROW(std::runtime_error, "Input is missing DENSITY\n");
        }

        // Set the properties.
        props_.resize(phase_usage_.num_phases);
        // Water PVT
        if (phase_usage_.phase_used[Aqua]) {
            if (deck.hasField("PVTW")) {
                props_[phase_usage_.phase_pos[Aqua]].reset(new SinglePvtConstCompr(deck.getPVTW().pvtw_));
            } else {
                // Eclipse 100 default.
                props_[phase_usage_.phase_pos[Aqua]].reset(new SinglePvtConstCompr(0.5*Opm::prefix::centi*Opm::unit::Poise));
            }
        }
        // Oil PVT
        if (phase_usage_.phase_used[Liquid]) {
            if (deck.hasField("PVDO")) {
                if (samples > 0) {
                    props_[phase_usage_.phase_pos[Liquid]].reset(new SinglePvtDeadSpline(deck.getPVDO().pvdo_, samples));
                } else {
                    props_[phase_usage_.phase_pos[Liquid]].reset(new SinglePvtDead(deck.getPVDO().pvdo_));
                }
            } else if (deck.hasField("PVTO")) {

                props_[phase_usage_.phase_pos[Liquid]].reset(new SinglePvtLiveOil(deck.getPVTO().pvto_));
            } else if (deck.hasField("PVCDO")) {
                props_[phase_usage_.phase_pos[Liquid]].reset(new SinglePvtConstCompr(deck.getPVCDO().pvcdo_));
            } else {
                OPM_THROW(std::runtime_error, "Input is missing PVDO or PVTO\n");
            }
        }
        // Gas PVT
        if (phase_usage_.phase_used[Vapour]) {
            if (deck.hasField("PVDG")) {
                if (samples > 0) {
                    props_[phase_usage_.phase_pos[Vapour]].reset(new SinglePvtDeadSpline(deck.getPVDG().pvdg_, samples));
                } else {
                    props_[phase_usage_.phase_pos[Vapour]].reset(new SinglePvtDead(deck.getPVDG().pvdg_));
                }
            // } else if (deck.hasField("PVTG")) {
            //     props_[phase_usage_.phase_pos[Vapour]].reset(new SinglePvtLiveGas(deck.getPVTG().pvtg_));
            } else {
                OPM_THROW(std::runtime_error, "Input is missing PVDG or PVTG\n");
            }
        }

        SaturationPropsFromDeck<SatFuncGwsegNonuniform>* ptr
            = new SaturationPropsFromDeck<SatFuncGwsegNonuniform>();
        satprops_.reset(ptr);
        ptr->init(deck, grid, -1);

        if (phase_usage_.num_phases != satprops_->numPhases()) {
            OPM_THROW(std::runtime_error, "BlackoilPropsAdFromDeck::BlackoilPropsAdFromDeck() - "
                  "Inconsistent number of phases in pvt data (" << phase_usage_.num_phases
                  << ") and saturation-dependent function data (" << satprops_->numPhases() << ").");
        }
    }
コード例 #13
0
    void BlackoilPvtProperties::init(const EclipseGridParser& deck, const int samples)
    {
        // If we need multiple regions, this class and the SinglePvt* classes must change.
        region_number_ = 0;

        phase_usage_ = phaseUsageFromDeck(deck);

        // Surface densities. Accounting for different orders in eclipse and our code.
        if (deck.hasField("DENSITY")) {
            const std::vector<double>& d = deck.getDENSITY().densities_[region_number_];
            enum { ECL_oil = 0, ECL_water = 1, ECL_gas = 2 };
            if (phase_usage_.phase_used[Aqua]) {
                densities_[phase_usage_.phase_pos[Aqua]]   = d[ECL_water];
            }
            if (phase_usage_.phase_used[Vapour]) {
                densities_[phase_usage_.phase_pos[Vapour]] = d[ECL_gas];
            }
            if (phase_usage_.phase_used[Liquid]) {
                densities_[phase_usage_.phase_pos[Liquid]] = d[ECL_oil];
            }
        } else {
            OPM_THROW(std::runtime_error, "Input is missing DENSITY\n");
        }

        // Set the properties.
        props_.resize(phase_usage_.num_phases);
        // Water PVT
        if (phase_usage_.phase_used[Aqua]) {
            if (deck.hasField("PVTW")) {
                props_[phase_usage_.phase_pos[Aqua]].reset(new SinglePvtConstCompr(deck.getPVTW().pvtw_));
            } else {
                // Eclipse 100 default.
                props_[phase_usage_.phase_pos[Aqua]].reset(new SinglePvtConstCompr(0.5*Opm::prefix::centi*Opm::unit::Poise));
            }
        }
        // Oil PVT
        if (phase_usage_.phase_used[Liquid]) {
            if (deck.hasField("PVDO")) {
                if (samples > 0) {
                    props_[phase_usage_.phase_pos[Liquid]].reset(new SinglePvtDeadSpline(deck.getPVDO().pvdo_, samples));
                } else {
                    props_[phase_usage_.phase_pos[Liquid]].reset(new SinglePvtDead(deck.getPVDO().pvdo_));
                }
            } else if (deck.hasField("PVTO")) {
                props_[phase_usage_.phase_pos[Liquid]].reset(new SinglePvtLiveOil(deck.getPVTO().pvto_));
            } else if (deck.hasField("PVCDO")) {
                props_[phase_usage_.phase_pos[Liquid]].reset(new SinglePvtConstCompr(deck.getPVCDO().pvcdo_));
            } else {
                OPM_THROW(std::runtime_error, "Input is missing PVDO or PVTO\n");
            }
        }
        // Gas PVT
        if (phase_usage_.phase_used[Vapour]) {
            if (deck.hasField("PVDG")) {
                if (samples > 0) {
                    props_[phase_usage_.phase_pos[Vapour]].reset(new SinglePvtDeadSpline(deck.getPVDG().pvdg_, samples));
                } else {
                    props_[phase_usage_.phase_pos[Vapour]].reset(new SinglePvtDead(deck.getPVDG().pvdg_));
                }
            } else if (deck.hasField("PVTG")) {
                props_[phase_usage_.phase_pos[Vapour]].reset(new SinglePvtLiveGas(deck.getPVTG().pvtg_));
            } else {
                OPM_THROW(std::runtime_error, "Input is missing PVDG or PVTG\n");
            }
        }

        // Must inform pvt property objects of phase structure.
        for (int i = 0; i < phase_usage_.num_phases; ++i) {
            props_[i]->setPhaseConfiguration(phase_usage_.num_phases, phase_usage_.phase_pos);
        }
    }
コード例 #14
0
ファイル: SatFuncGwseg.cpp プロジェクト: andlaus/opm-core
    void SatFuncGwsegUniform::init(const EclipseGridParser& deck,
                                   const int table_num,
                                   const PhaseUsage phase_usg,
                                   const int samples)
    {
        phase_usage = phase_usg;
        double swco = 0.0;
        double swmax = 1.0;
        if (phase_usage.phase_used[Aqua]) {
            const SWOF::table_t& swof_table = deck.getSWOF().swof_;
            const std::vector<double>& sw = swof_table[table_num][0];
            const std::vector<double>& krw = swof_table[table_num][1];
            const std::vector<double>& krow = swof_table[table_num][2];
            const std::vector<double>& pcow = swof_table[table_num][3];

            // Extend the tables with constant values such that the
            // derivatives at the endpoints are zero
            int n = sw.size();
            std::vector<double> sw_ex(n+2);
            std::vector<double> krw_ex(n+2);
            std::vector<double> krow_ex(n+2);
            std::vector<double> pcow_ex(n+2);

            SatFuncGwsegUniform::ExtendTable(sw,sw_ex,1);
            SatFuncGwsegUniform::ExtendTable(krw,krw_ex,0);
            SatFuncGwsegUniform::ExtendTable(krow,krow_ex,0);
            SatFuncGwsegUniform::ExtendTable(pcow,pcow_ex,0);

            buildUniformMonotoneTable(sw_ex, krw_ex,  samples, krw_);
            buildUniformMonotoneTable(sw_ex, krow_ex, samples, krow_);
            buildUniformMonotoneTable(sw_ex, pcow_ex, samples, pcow_);
            krocw_ = krow[0]; // At connate water -> ecl. SWOF
            swco = sw[0];
            smin_[phase_usage.phase_pos[Aqua]] = sw[0];
            swmax = sw.back();
            smax_[phase_usage.phase_pos[Aqua]] = sw.back();
        }
        if (phase_usage.phase_used[Vapour]) {
            const SGOF::table_t& sgof_table = deck.getSGOF().sgof_;
            const std::vector<double>& sg = sgof_table[table_num][0];
            const std::vector<double>& krg = sgof_table[table_num][1];
            const std::vector<double>& krog = sgof_table[table_num][2];
            const std::vector<double>& pcog = sgof_table[table_num][3];

            // Extend the tables with constant values such that the
            // derivatives at the endpoints are zero
            int n = sg.size();
            std::vector<double> sg_ex(n+2);
            std::vector<double> krg_ex(n+2);
            std::vector<double> krog_ex(n+2);
            std::vector<double> pcog_ex(n+2);

            SatFuncGwsegUniform::ExtendTable(sg,sg_ex,1);
            SatFuncGwsegUniform::ExtendTable(krg,krg_ex,0);
            SatFuncGwsegUniform::ExtendTable(krog,krog_ex,0);
            SatFuncGwsegUniform::ExtendTable(pcog,pcog_ex,0);

            buildUniformMonotoneTable(sg_ex, krg_ex,  samples, krg_);
            buildUniformMonotoneTable(sg_ex, krog_ex, samples, krog_);
            buildUniformMonotoneTable(sg_ex, pcog_ex, samples, pcog_);
            smin_[phase_usage.phase_pos[Vapour]] = sg[0];
            if (std::fabs(sg.back() + swco - 1.0) > 1e-3) {
                OPM_THROW(std::runtime_error, "Gas maximum saturation in SGOF table = " << sg.back() <<
                      ", should equal (1.0 - connate water sat) = " << (1.0 - swco));
            }
            smax_[phase_usage.phase_pos[Vapour]] = sg.back();
        }
        // These only consider water min/max sats. Consider gas sats?
        smin_[phase_usage.phase_pos[Liquid]] = 1.0 - swmax;
        smax_[phase_usage.phase_pos[Liquid]] = 1.0 - swco;
    }