Ejemplo n.º 1
0
    void BlackoilPVT::init(Opm::DeckConstPtr deck)
    {
        const auto eclipseState = std::make_shared<EclipseState>(deck);
	region_number_ = 0;

	// Surface densities. Accounting for different orders in eclipse and our code.
	if (deck->hasKeyword("DENSITY")) {
        Opm::DeckRecordConstPtr densityRecord =
            deck->getKeyword("DENSITY")->getRecord(/*regionIdx=*/0);
	    densities_[Aqua]   = densityRecord->getItem("WATER")->getSIDouble(0);
	    densities_[Vapour] = densityRecord->getItem("GAS")->getSIDouble(0);
	    densities_[Liquid] = densityRecord->getItem("OIL")->getSIDouble(0);
	} else {
	    OPM_THROW(std::runtime_error, "Input is missing DENSITY\n");
	}

        // Water PVT
        if (deck->hasKeyword("PVTW")) {
            water_props_.reset(new MiscibilityWater(deck->getKeyword("PVTW")));
        } else {
            water_props_.reset(new MiscibilityWater(0.5*Opm::prefix::centi*Opm::unit::Poise)); // Eclipse 100 default 
        }

        // Oil PVT
        const auto& pvdoTables = eclipseState->getPvdoTables();
        const auto& pvtoTables = eclipseState->getPvtoTables();
        if (!pvdoTables.empty()) {
            oil_props_.reset(new MiscibilityDead(pvdoTables[0]));
        } else if (pvtoTables.empty()) {
            oil_props_.reset(new MiscibilityLiveOil(pvtoTables[0]));
        } else if (deck->hasKeyword("PVCDO")) {
            auto *misc_water = new MiscibilityWater(0);
            misc_water->initFromPvcdo(deck->getKeyword("PVCDO"));
            oil_props_.reset(misc_water);
        } else {
            OPM_THROW(std::runtime_error, "Input is missing PVDO and PVTO\n");
        }

	// Gas PVT
        const auto& pvdgTables = eclipseState->getPvdgTables();
        const auto& pvtgTables = eclipseState->getPvtgTables();
        if (!pvdgTables.empty()) {
            gas_props_.reset(new MiscibilityDead(pvdgTables[0]));
        } else if (pvtgTables.empty()) {
            gas_props_.reset(new MiscibilityLiveGas(pvtgTables[0]));
        } else {
	    OPM_THROW(std::runtime_error, "Input is missing PVDG and PVTG\n");
        }
    }
Ejemplo n.º 2
0
    void BlackoilPvtProperties::init(Opm::DeckConstPtr deck,
                                     Opm::EclipseStateConstPtr eclipseState,
                                     int numSamples)
    {
        phase_usage_ = phaseUsageFromDeck(deck);

        // Surface densities. Accounting for different orders in eclipse and our code.
        Opm::DeckKeywordConstPtr densityKeyword = deck->getKeyword("DENSITY");
        int numRegions = densityKeyword->size();

        densities_.resize(numRegions);
        for (int regionIdx = 0; regionIdx < numRegions; ++regionIdx) {
            if (phase_usage_.phase_used[Liquid]) {
                densities_[regionIdx][phase_usage_.phase_pos[Liquid]]
                    = densityKeyword->getRecord(regionIdx)->getItem("OIL")->getSIDouble(0);
            }
            if (phase_usage_.phase_used[Aqua]) {
                densities_[regionIdx][phase_usage_.phase_pos[Aqua]]
                    = densityKeyword->getRecord(regionIdx)->getItem("WATER")->getSIDouble(0);
            }
            if (phase_usage_.phase_used[Vapour]) {
                densities_[regionIdx][phase_usage_.phase_pos[Vapour]]
                    = densityKeyword->getRecord(regionIdx)->getItem("GAS")->getSIDouble(0);
            }
        }

        // Resize the property objects container
        props_.resize(phase_usage_.num_phases);

        // Water PVT
        if (phase_usage_.phase_used[Aqua]) {
            // if water is used, we require the presence of the "PVTW"
            // keyword for now...
            std::shared_ptr<PvtConstCompr> pvtw(new PvtConstCompr);
            pvtw->initFromWater(deck->getKeyword("PVTW"));

            props_[phase_usage_.phase_pos[Aqua]] = pvtw;
        }

        {
            auto tables = eclipseState->getTableManager();
            // Oil PVT
            if (phase_usage_.phase_used[Liquid]) {
                // for oil, we support the "PVDO", "PVTO" and "PVCDO"
                // keywords...
                const auto &pvdoTables = tables->getPvdoTables();
                const auto &pvtoTables = tables->getPvtoTables();
                if (pvdoTables.size() > 0) {
                    if (numSamples > 0) {
                        auto splinePvt = std::shared_ptr<PvtDeadSpline>(new PvtDeadSpline);
                        splinePvt->initFromOil(pvdoTables, numSamples);
                        props_[phase_usage_.phase_pos[Liquid]] = splinePvt;
                    } else {
                        auto deadPvt = std::shared_ptr<PvtDead>(new PvtDead);
                        deadPvt->initFromOil(pvdoTables);
                        props_[phase_usage_.phase_pos[Liquid]] = deadPvt;
                    }
                } else if (pvtoTables.size() > 0) {
                    props_[phase_usage_.phase_pos[Liquid]].reset(new PvtLiveOil(pvtoTables));
                } else if (deck->hasKeyword("PVCDO")) {
                    std::shared_ptr<PvtConstCompr> pvcdo(new PvtConstCompr);
                    pvcdo->initFromOil(deck->getKeyword("PVCDO"));

                    props_[phase_usage_.phase_pos[Liquid]] = pvcdo;
                } else {
                    OPM_THROW(std::runtime_error, "Input is missing PVDO, PVCDO or PVTO\n");
                }
            }
            // Gas PVT
            if (phase_usage_.phase_used[Vapour]) {
                // gas can be specified using the "PVDG" or "PVTG" keywords...
                const auto &pvdgTables = tables->getPvdgTables();
                const auto &pvtgTables = tables->getPvtgTables();
                if (pvdgTables.size() > 0) {
                    if (numSamples > 0) {
                        std::shared_ptr<PvtDeadSpline> splinePvt(new PvtDeadSpline);
                        splinePvt->initFromGas(pvdgTables, numSamples);

                        props_[phase_usage_.phase_pos[Vapour]] = splinePvt;
                    } else {
                        std::shared_ptr<PvtDead> deadPvt(new PvtDead);
                        deadPvt->initFromGas(pvdgTables);

                        props_[phase_usage_.phase_pos[Vapour]] = deadPvt;
                    }
                } else if (pvtgTables.size() > 0) {
                    props_[phase_usage_.phase_pos[Vapour]].reset(new PvtLiveGas(pvtgTables));
                } else {
                    OPM_THROW(std::runtime_error, "Input is missing PVDG or PVTG\n");
                }
            }
        }
    }
        /// set the tables which specify the temperature dependence of the oil viscosity
        void initFromDeck(std::shared_ptr<const PvtInterface> isothermalPvt,
                          const Opm::Deck& deck,
                          const Opm::EclipseState& eclipseState)
        {
            isothermalPvt_ = isothermalPvt;

            int numRegions;
            auto tables = eclipseState->getTableManager();

            if (deck->hasKeyword("PVTO"))
                numRegions = tables->getPvtoTables().size();
            else if (deck->hasKeyword("PVDO"))
                numRegions = tables->getPvdoTables().size();
            else if (deck->hasKeyword("PVCDO"))
                numRegions = deck->getKeyword("PVCDO").size();
            else
                OPM_THROW(std::runtime_error, "Oil phase was not initialized using a known way");

            // viscosity
            if (deck->hasKeyword("VISCREF")) {
                oilvisctTables_ = &tables->getOilvisctTables();
                const auto& viscrefKeyword = deck->getKeyword("VISCREF");

                assert(int(oilvisctTables_->size()) == numRegions);
                assert(int(viscrefKeyword.size()) == numRegions);

                viscrefPress_.resize(numRegions);
                viscrefRs_.resize(numRegions);
                muRef_.resize(numRegions);
                for (int regionIdx = 0; regionIdx < numRegions; ++regionIdx) {
                    const auto& viscrefRecord = viscrefKeyword.getRecord(regionIdx);
                    viscrefPress_[regionIdx] = viscrefRecord.getItem("REFERENCE_PRESSURE").getSIDouble(0);
                    viscrefRs_[regionIdx] = viscrefRecord.getItem("REFERENCE_RS").getSIDouble(0);

                    // temperature used to calculate the reference viscosity [K]. the
                    // value does not really matter if the underlying PVT object really
                    // is isothermal...
                    double Tref = 273.15 + 20;

                    // compute the reference viscosity using the isothermal PVT object.
                    double tmp1, tmp2;
                    isothermalPvt_->mu(1,
                                       &regionIdx,
                                       &viscrefPress_[regionIdx],
                                       &Tref,
                                       &viscrefRs_[regionIdx],
                                       &muRef_[regionIdx],
                                       &tmp1,
                                       &tmp2);
                }
            }

            // quantities required for density. note that we just always use the values
            // for the first EOS. (since EOS != PVT region.)
            tref_ = 0.0;
            if (deck->hasKeyword("THERMEX1")) {
                oilCompIdx_ = deck->getKeyword("OCOMPIDX").getRecord(0).getItem("OIL_COMPONENT_INDEX").get< int >(0) - 1;

                // always use the values of the first EOS
                tref_ = deck->getKeyword("TREF").getRecord(0).getItem("TEMPERATURE").getSIDouble(oilCompIdx_);
                pref_ = deck->getKeyword("PREF").getRecord(0).getItem("PRESSURE").getSIDouble(oilCompIdx_);
                cref_ = deck->getKeyword("CREF").getRecord(0).getItem("COMPRESSIBILITY").getSIDouble(oilCompIdx_);
                thermex1_ = deck->getKeyword("THERMEX1").getRecord(0).getItem("EXPANSION_COEFF").getSIDouble(oilCompIdx_);
            }
        }