Esempio n. 1
0
    /*!
     * \brief Initialize the oil parameters via the data specified by the PVDO ECL keyword.
     */
    void initFromDeck(const Deck& deck, const EclipseState& eclState)
    {
        const auto& pvdoTables = eclState.getTableManager().getPvdoTables();
        const auto& densityKeyword = deck.getKeyword("DENSITY");

        assert(pvdoTables.size() == densityKeyword.size());

        size_t numRegions = pvdoTables.size();
        setNumRegions(numRegions);

        for (unsigned regionIdx = 0; regionIdx < numRegions; ++ regionIdx) {
            Scalar rhoRefO = densityKeyword.getRecord(regionIdx).getItem("OIL").getSIDouble(0);
            Scalar rhoRefG = densityKeyword.getRecord(regionIdx).getItem("GAS").getSIDouble(0);
            Scalar rhoRefW = densityKeyword.getRecord(regionIdx).getItem("WATER").getSIDouble(0);

            setReferenceDensities(regionIdx, rhoRefO, rhoRefG, rhoRefW);

            const auto& pvdoTable = pvdoTables.getTable<PvdoTable>(regionIdx);

            const auto& BColumn(pvdoTable.getFormationFactorColumn());
            std::vector<Scalar> invBColumn(BColumn.size());
            for (unsigned i = 0; i < invBColumn.size(); ++i)
                invBColumn[i] = 1/BColumn[i];

            inverseOilB_[regionIdx].setXYArrays(pvdoTable.numRows(),
                                                pvdoTable.getPressureColumn(),
                                                invBColumn);
            oilMu_[regionIdx].setXYArrays(pvdoTable.numRows(),
                                          pvdoTable.getPressureColumn(),
                                          pvdoTable.getViscosityColumn());
        }

        initEnd();
    }
Esempio n. 2
0
 Setup( const char* path, const ParseContext& parseContext = ParseContext( )) :
     deck( Parser().parseFile( path, parseContext ) ),
     es( deck, parseContext ),
     grid( es.getInputGrid( ) ),
     schedule( deck, grid, es.get3DProperties(), es.runspec().phases(), parseContext),
     summary_config( deck, schedule, es.getTableManager( ), parseContext)
 {
     auto& io_config = es.getIOConfig();
     io_config.setEclCompatibleRST(false);
 }
Esempio n. 3
0
    /*!
     * \brief Implement the temperature part of the water PVT properties.
     */
    void initFromDeck(const Deck& deck,
                      const EclipseState& eclState)
    {
        //////
        // initialize the isothermal part
        //////
        isothermalPvt_ = new IsothermalPvt;
        isothermalPvt_->initFromDeck(deck, eclState);

        //////
        // initialize the thermal part
        //////
        const auto& tables = eclState.getTableManager();

        enableThermalDensity_ = deck.hasKeyword("WATDENT");
        enableThermalViscosity_ = deck.hasKeyword("VISCREF");

        unsigned numRegions = isothermalPvt_->numRegions();
        setNumRegions(numRegions);

        if (enableThermalDensity_) {
            const auto& watdentKeyword = deck.getKeyword("WATDENT");

            assert(watdentKeyword.size() == numRegions);
            for (unsigned regionIdx = 0; regionIdx < numRegions; ++regionIdx) {
                const auto& watdentRecord = watdentKeyword.getRecord(regionIdx);

                watdentRefTemp_[regionIdx] = watdentRecord.getItem("REFERENCE_TEMPERATURE").getSIDouble(0);
                watdentCT1_[regionIdx] = watdentRecord.getItem("EXPANSION_COEFF_LINEAR").getSIDouble(0);
                watdentCT2_[regionIdx] = watdentRecord.getItem("EXPANSION_COEFF_QUADRATIC").getSIDouble(0);
            }
        }

        if (enableThermalViscosity_) {
            const auto& viscrefKeyword = deck.getKeyword("VISCREF");

            const auto& watvisctTables = tables.getWatvisctTables();

            assert(watvisctTables.size() == numRegions);
            assert(viscrefKeyword.size() == numRegions);

            for (unsigned regionIdx = 0; regionIdx < numRegions; ++ regionIdx) {
                const auto& T = watvisctTables[regionIdx].getColumn("Temperature").vectorCopy();
                const auto& mu = watvisctTables[regionIdx].getColumn("Viscosity").vectorCopy();
                watvisctCurves_[regionIdx].setXYContainers(T, mu);

                const auto& viscrefRecord = viscrefKeyword.getRecord(regionIdx);
                viscrefPress_[regionIdx] = viscrefRecord.getItem("REFERENCE_PRESSURE").getSIDouble(0);
            }
        }
    }
Esempio n. 4
0
std::vector<int>
Opm::RestartIO::Helpers::
createInteHead(const EclipseState& es,
               const EclipseGrid&  grid,
               const Schedule&     sched,
               const double        simTime,
               const int           num_solver_steps,
               const int           lookup_step)
{
    const auto  nwgmax = maxGroupSize(sched, lookup_step);
    const auto  ngmax  = numGroupsInField(sched, lookup_step);
    const auto& rspec  = es.runspec();
    const auto& tdim   = es.getTableManager();
    const auto& rdim   = tdim.getRegdims();

    const auto ih = InteHEAD{}
        .dimensions         (grid.getNXYZ())
        .numActive          (static_cast<int>(grid.getNumActive()))
        .unitConventions    (getUnitConvention(es.getDeckUnitSystem()))
        .wellTableDimensions(getWellTableDims(nwgmax, rspec, sched, lookup_step))
        .calendarDate       (getSimulationTimePoint(sched.posixStartTime(), simTime))
        .activePhases       (getActivePhases(rspec))
             // The numbers below have been determined experimentally to work
             // across a range of reference cases, but are not guaranteed to be
             // universally valid.
        .params_NWELZ       (155, 122, 130, 3) // n{isxz}welz: number of data elements per well in {ISXZ}WELL
        .params_NCON        (25, 40, 58)       // n{isx}conz: number of data elements per completion in ICON
        .params_GRPZ        (getNGRPZ(nwgmax, ngmax, rspec))
             // ncamax: max number of analytical aquifer connections
             // n{isx}aaqz: number of data elements per aquifer in {ISX}AAQ
             // n{isa}caqz: number of data elements per aquifer connection in {ISA}CAQ
        .params_NAAQZ       (1, 18, 24, 10, 7, 2, 4)
        .stepParam          (num_solver_steps, lookup_step)
        .tuningParam        (getTuningPars(sched.getTuning(), lookup_step))
        .wellSegDimensions  (getWellSegDims(rspec, sched, lookup_step))
        .regionDimensions   (getRegDims(tdim, rdim))
        .ngroups            ({ ngmax })
        .variousParam       (201702, 100)  // Output should be compatible with Eclipse 100, 2017.02 version.
        ;

    return ih.data();
}
Esempio n. 5
0
    /*!
     * \brief Implement the temperature part of the gas PVT properties.
     */
    void initFromDeck(const Deck& deck,
                      const EclipseState& eclState)
    {
        //////
        // initialize the isothermal part
        //////
        isothermalPvt_ = new IsothermalPvt;
        isothermalPvt_->initFromDeck(deck, eclState);

        //////
        // initialize the thermal part
        //////
        const auto& tables = eclState.getTableManager();

        enableThermalDensity_ = deck.hasKeyword("TREF");
        enableThermalViscosity_ = deck.hasKeyword("GASVISCT");

        unsigned numRegions = isothermalPvt_->numRegions();
        setNumRegions(numRegions);

        // viscosity
        if (enableThermalViscosity_) {
            const auto& gasvisctTables = tables.getGasvisctTables();
            int gasCompIdx = deck.getKeyword("GCOMPIDX").getRecord(0).getItem("GAS_COMPONENT_INDEX").get< int >(0) - 1;
            std::string gasvisctColumnName = "Viscosity"+std::to_string(static_cast<long long>(gasCompIdx));

            for (unsigned regionIdx = 0; regionIdx < numRegions; ++regionIdx) {
                const auto& T = gasvisctTables[regionIdx].getColumn("Temperature").vectorCopy();
                const auto& mu = gasvisctTables[regionIdx].getColumn(gasvisctColumnName).vectorCopy();
                gasvisctCurves_[regionIdx].setXYContainers(T, mu);
            }
        }

        // quantities required for density. note that we just always use the values
        // for the first EOS. (since EOS != PVT region.)
        refTemp_ = 0.0;
        if (enableThermalDensity_) {
            refTemp_ = deck.getKeyword("TREF").getRecord(0).getItem("TEMPERATURE").getSIDouble(0);
        }
    }
Esempio n. 6
0
    AquiferCT::AquiferCT(const EclipseState& eclState, const Deck& deck)
    { 
        if (!deck.hasKeyword("AQUCT"))
            return;

        const auto& aquctKeyword = deck.getKeyword("AQUCT");

        for (auto& aquctRecord : aquctKeyword){
  
            AquiferCT::AQUCT_data data;
    
            data.aquiferID = aquctRecord.getItem("AQUIFER_ID").template get<int>(0);
            data.h = aquctRecord.getItem("THICKNESS_AQ").getSIDouble(0);
            data.phi_aq = aquctRecord.getItem("PORO_AQ").getSIDouble(0);
            data.d0 = aquctRecord.getItem("DAT_DEPTH").getSIDouble(0);
            data.C_t = aquctRecord.getItem("C_T").getSIDouble(0);
            data.r_o = aquctRecord.getItem("RAD").getSIDouble(0);
            data.k_a = aquctRecord.getItem("PERM_AQ").getSIDouble(0);
            data.theta = aquctRecord.getItem("INFLUENCE_ANGLE").getSIDouble(0);
            data.c1 = 0.008527; // We are using SI
            data.c2 = 6.283;
            data.inftableID = aquctRecord.getItem("TABLE_NUM_INFLUENCE_FN").template get<int>(0);
            data.pvttableID = aquctRecord.getItem("TABLE_NUM_WATER_PRESS").template get<int>(0);

            // Get the correct influence table values
            if (data.inftableID > 1){
                const auto& aqutabTable = eclState.getTableManager().getAqutabTables().getTable(data.inftableID - 2);
                const auto& aqutab_tdColumn = aqutabTable.getColumn(0);
                const auto& aqutab_piColumn = aqutabTable.getColumn(1);
                data.td = aqutab_tdColumn.vectorCopy();
                data.pi = aqutab_piColumn.vectorCopy();
                }
            else
                {
                    set_default_tables(data.td,data.pi);
                }
                m_aquct.push_back( std::move(data) );
            }     
    }
Esempio n. 7
0
    /*!
     * \brief Implement the temperature part of the oil PVT properties.
     */
    void initFromDeck(const Deck& deck,
                      const EclipseState& eclState)
    {
        //////
        // initialize the isothermal part
        //////
        isothermalPvt_ = new IsothermalPvt;
        isothermalPvt_->initFromDeck(deck, eclState);

        //////
        // initialize the thermal part
        //////
        const auto& tables = eclState.getTableManager();

        enableThermalDensity_ = deck.hasKeyword("OILDENT");
        enableThermalViscosity_ = deck.hasKeyword("OILVISCT");
        enableInternalEnergy_ = deck.hasKeyword("SPECHEAT");

        unsigned numRegions = isothermalPvt_->numRegions();
        setNumRegions(numRegions);

        // viscosity
        if (deck.hasKeyword("OILVISCT")) {
            if (!deck.hasKeyword("VISCREF"))
                throw std::runtime_error("VISCREF is required when OILVISCT is present");

            const auto& oilvisctTables = tables.getOilvisctTables();
            const auto& viscrefKeyword = deck.getKeyword("VISCREF");

            assert(oilvisctTables.size() == numRegions);
            assert(viscrefKeyword.size() == numRegions);

            for (unsigned regionIdx = 0; regionIdx < numRegions; ++regionIdx) {
                const auto& TCol = oilvisctTables[regionIdx].getColumn("Temperature").vectorCopy();
                const auto& muCol = oilvisctTables[regionIdx].getColumn("Viscosity").vectorCopy();
                oilvisctCurves_[regionIdx].setXYContainers(TCol, muCol);

                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...
                Scalar Tref = 273.15 + 20;

                // compute the reference viscosity using the isothermal PVT object.
                viscRef_[regionIdx] =
                    isothermalPvt_->viscosity(regionIdx,
                                              Tref,
                                              viscrefPress_[regionIdx],
                                              viscrefRs_[regionIdx]);
            }
        }

        // temperature dependence of oil density
        if (enableThermalDensity_) {
            const auto& oildentKeyword = deck.getKeyword("OILDENT");

            assert(oildentKeyword.size() == numRegions);
            for (unsigned regionIdx = 0; regionIdx < numRegions; ++regionIdx) {
                const auto& oildentRecord = oildentKeyword.getRecord(regionIdx);

                oildentRefTemp_[regionIdx] = oildentRecord.getItem("REFERENCE_TEMPERATURE").getSIDouble(0);
                oildentCT1_[regionIdx] = oildentRecord.getItem("EXPANSION_COEFF_LINEAR").getSIDouble(0);
                oildentCT2_[regionIdx] = oildentRecord.getItem("EXPANSION_COEFF_QUADRATIC").getSIDouble(0);
            }
        }

        if (deck.hasKeyword("SPECHEAT")) {
            // the specific internal energy of liquid oil. be aware that ecl only specifies the
            // heat capacity (via the SPECHEAT keyword) and we need to integrate it
            // ourselfs to get the internal energy
            for (unsigned regionIdx = 0; regionIdx < numRegions; ++regionIdx) {
                const auto& specheatTable = tables.getSpecheatTables()[regionIdx];
                const auto& temperatureColumn = specheatTable.getColumn("TEMPERATURE");
                const auto& cvOilColumn = specheatTable.getColumn("CV_OIL");

                std::vector<double> uSamples(temperatureColumn.size());

                Scalar u = temperatureColumn[0]*cvOilColumn[0];
                for (size_t i = 0;; ++i) {
                    uSamples[i] = u;

                    if (i >= temperatureColumn.size() - 1)
                        break;

                    // integrate to the heat capacity from the current sampling point to the next
                    // one. this leads to a quadratic polynomial.
                    Scalar c_v0 = cvOilColumn[i];
                    Scalar c_v1 = cvOilColumn[i + 1];
                    Scalar T0 = temperatureColumn[i];
                    Scalar T1 = temperatureColumn[i + 1];
                    u += 0.5*(c_v0 + c_v1)*(T1 - T0);
                }

                internalEnergyCurves_[regionIdx].setXYContainers(temperatureColumn.vectorCopy(), uSamples);
            }
        }
    }
Esempio n. 8
0
    /*!
     * \brief Initialize the oil parameters via the data specified by the PVTO ECL keyword.
     */
    void initFromDeck(const Deck& deck, const EclipseState& eclState)
    {
        const auto& pvtoTables = eclState.getTableManager().getPvtoTables();
        const auto& densityKeyword = deck.getKeyword("DENSITY");

        assert(pvtoTables.size() == densityKeyword.size());

        size_t numRegions = pvtoTables.size();
        setNumRegions(numRegions);

        for (unsigned regionIdx = 0; regionIdx < numRegions; ++ regionIdx) {
            Scalar rhoRefO = densityKeyword.getRecord(regionIdx).getItem("OIL").getSIDouble(0);
            Scalar rhoRefG = densityKeyword.getRecord(regionIdx).getItem("GAS").getSIDouble(0);
            Scalar rhoRefW = densityKeyword.getRecord(regionIdx).getItem("WATER").getSIDouble(0);

            setReferenceDensities(regionIdx, rhoRefO, rhoRefG, rhoRefW);
        }

        // initialize the internal table objects
        for (unsigned regionIdx = 0; regionIdx < numRegions; ++ regionIdx) {
            const auto& pvtoTable = pvtoTables[regionIdx];

            const auto& saturatedTable = pvtoTable.getSaturatedTable();
            assert(saturatedTable.numRows() > 1);

            auto& oilMu = oilMuTable_[regionIdx];
            auto& satOilMu = saturatedOilMuTable_[regionIdx];
            auto& invOilB = inverseOilBTable_[regionIdx];
            auto& invSatOilB = inverseSaturatedOilBTable_[regionIdx];
            auto& gasDissolutionFac = saturatedGasDissolutionFactorTable_[regionIdx];
            std::vector<Scalar> invSatOilBArray;
            std::vector<Scalar> satOilMuArray;

            // extract the table for the gas dissolution and the oil formation volume factors
            for (unsigned outerIdx = 0; outerIdx < saturatedTable.numRows(); ++ outerIdx) {
                Scalar Rs    = saturatedTable.get("RS", outerIdx);
                Scalar BoSat = saturatedTable.get("BO", outerIdx);
                Scalar muoSat = saturatedTable.get("MU", outerIdx);

                satOilMuArray.push_back(muoSat);
                invSatOilBArray.push_back(1.0/BoSat);

                invOilB.appendXPos(Rs);
                oilMu.appendXPos(Rs);

                assert(invOilB.numX() == outerIdx + 1);
                assert(oilMu.numX() == outerIdx + 1);

                const auto& underSaturatedTable = pvtoTable.getUnderSaturatedTable(outerIdx);
                size_t numRows = underSaturatedTable.numRows();
                for (unsigned innerIdx = 0; innerIdx < numRows; ++ innerIdx) {
                    Scalar po = underSaturatedTable.get("P", innerIdx);
                    Scalar Bo = underSaturatedTable.get("BO", innerIdx);
                    Scalar muo = underSaturatedTable.get("MU", innerIdx);

                    invOilB.appendSamplePoint(outerIdx, po, 1.0/Bo);
                    oilMu.appendSamplePoint(outerIdx, po, muo);
                }
            }

            // update the tables for the formation volume factor and for the gas
            // dissolution factor of saturated oil
            {
                const auto& tmpPressureColumn = saturatedTable.getColumn("P");
                const auto& tmpGasSolubilityColumn = saturatedTable.getColumn("RS");

                invSatOilB.setXYContainers(tmpPressureColumn, invSatOilBArray);
                satOilMu.setXYContainers(tmpPressureColumn, satOilMuArray);
                gasDissolutionFac.setXYContainers(tmpPressureColumn, tmpGasSolubilityColumn);
            }

            updateSaturationPressure_(regionIdx);
            // make sure to have at least two sample points per Rs value
            for (unsigned xIdx = 0; xIdx < invOilB.numX(); ++xIdx) {
                // a single sample point is definitely needed
                assert(invOilB.numY(xIdx) > 0);

                // everything is fine if the current table has two or more sampling points
                // for a given mole fraction
                if (invOilB.numY(xIdx) > 1)
                    continue;

                // find the master table which will be used as a template to extend the
                // current line. We define master table as the first table which has values
                // for undersaturated oil...
                size_t masterTableIdx = xIdx + 1;
                for (; masterTableIdx < saturatedTable.numRows(); ++masterTableIdx)
                {
                    if (pvtoTable.getUnderSaturatedTable(masterTableIdx).numRows() > 1)
                        break;
                }

                if (masterTableIdx >= saturatedTable.numRows())
                    throw std::runtime_error("PVTO tables are invalid: The last table must exhibit at least one "
                                             "entry for undersaturated oil!");

                // extend the current table using the master table.
                extendPvtoTable_(regionIdx,
                                 xIdx,
                                 pvtoTable.getUnderSaturatedTable(xIdx),
                                 pvtoTable.getUnderSaturatedTable(masterTableIdx));
            }
        }

        vapPar2_ = 0.0;
        if (deck.hasKeyword("VAPPARS")) {
            const auto& vapParsKeyword = deck.getKeyword("VAPPARS");
            vapPar2_ = vapParsKeyword.getRecord(0).getItem("OIL_DENSITY_PROPENSITY").template get<double>(0);
        }

        initEnd();
    }
Esempio n. 9
0
    /*!
     * \brief Implement the temperature part of the gas PVT properties.
     */
    void initFromDeck(const Deck& deck,
                      const EclipseState& eclState)
    {
        //////
        // initialize the isothermal part
        //////
        isothermalPvt_ = new IsothermalPvt;
        isothermalPvt_->initFromDeck(deck, eclState);

        //////
        // initialize the thermal part
        //////
        const auto& tables = eclState.getTableManager();

        enableThermalDensity_ = deck.hasKeyword("GASDENT");
        enableThermalViscosity_ = deck.hasKeyword("GASVISCT");
        enableInternalEnergy_ = deck.hasKeyword("SPECHEAT");

        unsigned numRegions = isothermalPvt_->numRegions();
        setNumRegions(numRegions);

        // viscosity
        if (enableThermalViscosity_) {
            const auto& gasvisctTables = tables.getGasvisctTables();
            int gasCompIdx = deck.getKeyword("GCOMPIDX").getRecord(0).getItem("GAS_COMPONENT_INDEX").get< int >(0) - 1;
            std::string gasvisctColumnName = "Viscosity"+std::to_string(static_cast<long long>(gasCompIdx));

            for (unsigned regionIdx = 0; regionIdx < numRegions; ++regionIdx) {
                const auto& T = gasvisctTables[regionIdx].getColumn("Temperature").vectorCopy();
                const auto& mu = gasvisctTables[regionIdx].getColumn(gasvisctColumnName).vectorCopy();
                gasvisctCurves_[regionIdx].setXYContainers(T, mu);
            }
        }

        // temperature dependence of gas density
        if (enableThermalDensity_) {
            const auto& gasdentKeyword = deck.getKeyword("GASDENT");

            assert(gasdentKeyword.size() == numRegions);
            for (unsigned regionIdx = 0; regionIdx < numRegions; ++regionIdx) {
                const auto& gasdentRecord = gasdentKeyword.getRecord(regionIdx);

                gasdentRefTemp_[regionIdx] = gasdentRecord.getItem("REFERENCE_TEMPERATURE").getSIDouble(0);
                gasdentCT1_[regionIdx] = gasdentRecord.getItem("EXPANSION_COEFF_LINEAR").getSIDouble(0);
                gasdentCT2_[regionIdx] = gasdentRecord.getItem("EXPANSION_COEFF_QUADRATIC").getSIDouble(0);
            }
        }

        if (deck.hasKeyword("SPECHEAT")) {
            // the specific internal energy of gas. be aware that ecl only specifies the heat capacity
            // (via the SPECHEAT keyword) and we need to integrate it ourselfs to get the
            // internal energy
            for (unsigned regionIdx = 0; regionIdx < numRegions; ++regionIdx) {
                const auto& specHeatTable = tables.getSpecheatTables()[regionIdx];
                const auto& temperatureColumn = specHeatTable.getColumn("TEMPERATURE");
                const auto& cvGasColumn = specHeatTable.getColumn("CV_GAS");

                std::vector<double> uSamples(temperatureColumn.size());

                // the specific enthalpy of vaporization. since ECL does not seem to
                // feature a proper way to specify this quantity, we use the value for
                // methane. A proper model would also need to consider the enthalpy
                // change due to dissolution, i.e. the enthalpies of the gas and oil
                // phases should depend on the phase composition
                const Scalar hVap = 480.6e3; // [J / kg]

                Scalar u = temperatureColumn[0]*cvGasColumn[0] + hVap;
                for (size_t i = 0;; ++i) {
                    uSamples[i] = u;

                    if (i >= temperatureColumn.size() - 1)
                        break;

                    // integrate to the heat capacity from the current sampling point to the next
                    // one. this leads to a quadratic polynomial.
                    Scalar c_v0 = cvGasColumn[i];
                    Scalar c_v1 = cvGasColumn[i + 1];
                    Scalar T0 = temperatureColumn[i];
                    Scalar T1 = temperatureColumn[i + 1];
                    u += 0.5*(c_v0 + c_v1)*(T1 - T0);
                }

                internalEnergyCurves_[regionIdx].setXYContainers(temperatureColumn.vectorCopy(), uSamples);
            }
        }
    }