mirror of
				https://github.com/OPM/opm-simulators.git
				synced 2025-02-25 18:55:30 -06:00 
			
		
		
		
	check operability injectors
This commit is contained in:
		@@ -316,10 +316,10 @@ namespace Opm
 | 
			
		||||
        double maxPerfPress(const Simulator& ebos_simulator) const;
 | 
			
		||||
 | 
			
		||||
        // check whether the well is operable under BHP limit with current reservoir condition
 | 
			
		||||
        virtual void checkOperabilityUnderBHPLimitProducer(const WellState& well_state, const Simulator& ebos_simulator, DeferredLogger& deferred_logger) override;
 | 
			
		||||
        virtual void checkOperabilityUnderBHPLimit(const WellState& well_state, const Simulator& ebos_simulator, DeferredLogger& deferred_logger) override;
 | 
			
		||||
 | 
			
		||||
        // check whether the well is operable under THP limit with current reservoir condition
 | 
			
		||||
        virtual void checkOperabilityUnderTHPLimitProducer(const Simulator& ebos_simulator, const WellState& well_state, DeferredLogger& deferred_logger) override;
 | 
			
		||||
        virtual void checkOperabilityUnderTHPLimit(const Simulator& ebos_simulator, const WellState& well_state, DeferredLogger& deferred_logger) override;
 | 
			
		||||
 | 
			
		||||
        // updating the inflow based on the current reservoir condition
 | 
			
		||||
        virtual void updateIPR(const Simulator& ebos_simulator, DeferredLogger& deferred_logger) const override;
 | 
			
		||||
 
 | 
			
		||||
@@ -1128,7 +1128,7 @@ namespace Opm
 | 
			
		||||
    template<typename TypeTag>
 | 
			
		||||
    void
 | 
			
		||||
    MultisegmentWell<TypeTag>::
 | 
			
		||||
    checkOperabilityUnderBHPLimitProducer(const WellState& /*well_state*/, const Simulator& ebos_simulator, DeferredLogger& deferred_logger)
 | 
			
		||||
    checkOperabilityUnderBHPLimit(const WellState& /*well_state*/, const Simulator& ebos_simulator, DeferredLogger& deferred_logger)
 | 
			
		||||
    {
 | 
			
		||||
        const auto& summaryState = ebos_simulator.vanguard().summaryState();
 | 
			
		||||
        const double bhp_limit = Base::mostStrictBhpFromBhpLimits(summaryState);
 | 
			
		||||
@@ -1139,11 +1139,11 @@ namespace Opm
 | 
			
		||||
            // if the BHP limit is not defaulted or the well does not have a THP limit
 | 
			
		||||
            // we need to check the BHP limit
 | 
			
		||||
 | 
			
		||||
            double temp = 0;
 | 
			
		||||
            double ipr_rate = 0;
 | 
			
		||||
            for (int p = 0; p < this->number_of_phases_; ++p) {
 | 
			
		||||
                temp += this->ipr_a_[p] - this->ipr_b_[p] * bhp_limit;
 | 
			
		||||
                ipr_rate += this->ipr_a_[p] - this->ipr_b_[p] * bhp_limit;
 | 
			
		||||
            }
 | 
			
		||||
            if (temp < 0.) {
 | 
			
		||||
            if ( (this->isProducer() && ipr_rate < 0.) || (this->isInjector() && ipr_rate > 0.) ) {
 | 
			
		||||
                this->operability_status_.operable_under_only_bhp_limit = false;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
@@ -1156,10 +1156,8 @@ namespace Opm
 | 
			
		||||
                computeWellRatesWithBhp(ebos_simulator, bhp_limit, well_rates_bhp_limit, deferred_logger);
 | 
			
		||||
 | 
			
		||||
                const double thp = this->calculateThpFromBhp(well_rates_bhp_limit, bhp_limit, getRefDensity(), deferred_logger);
 | 
			
		||||
 | 
			
		||||
                const double thp_limit = this->getTHPConstraint(summaryState);
 | 
			
		||||
 | 
			
		||||
                if (thp < thp_limit) {
 | 
			
		||||
                if ( (this->isProducer() && thp < thp_limit) || (this->isInjector() && thp > thp_limit) ) {
 | 
			
		||||
                    this->operability_status_.obey_thp_limit_under_bhp_limit = false;
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
@@ -1185,12 +1183,6 @@ namespace Opm
 | 
			
		||||
    {
 | 
			
		||||
        // TODO: not handling solvent related here for now
 | 
			
		||||
 | 
			
		||||
        // TODO: it only handles the producers for now
 | 
			
		||||
        // the formular for the injectors are not formulated yet
 | 
			
		||||
        if (this->isInjector()) {
 | 
			
		||||
            return;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        // initialize all the values to be zero to begin with
 | 
			
		||||
        std::fill(this->ipr_a_.begin(), this->ipr_a_.end(), 0.);
 | 
			
		||||
        std::fill(this->ipr_b_.begin(), this->ipr_b_.end(), 0.);
 | 
			
		||||
@@ -1234,12 +1226,10 @@ namespace Opm
 | 
			
		||||
            const double h_perf = cell_perf_press_diff + perf_seg_press_diff + seg_bhp_press_diff;
 | 
			
		||||
            const double pressure_diff = pressure_cell - h_perf;
 | 
			
		||||
 | 
			
		||||
            // Let us add a check, since the pressure is calculated based on zero value BHP
 | 
			
		||||
            // it should not be negative anyway. If it is negative, we might need to re-formulate
 | 
			
		||||
            // to taking into consideration the crossflow here.
 | 
			
		||||
            if (pressure_diff <= 0.) {
 | 
			
		||||
                deferred_logger.warning("NON_POSITIVE_DRAWDOWN_IPR",
 | 
			
		||||
                                "non-positive drawdown found when updateIPR for well " + this->name());
 | 
			
		||||
            // do not take into consideration the crossflow here.
 | 
			
		||||
            if ( (this->isProducer() && pressure_diff < 0.) || (this->isInjector() && pressure_diff > 0.) ) {
 | 
			
		||||
                deferred_logger.debug("CROSSFLOW_IPR",
 | 
			
		||||
                                "cross flow found when updateIPR for well " + this->name());
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            // the well index associated with the connection
 | 
			
		||||
@@ -1288,10 +1278,11 @@ namespace Opm
 | 
			
		||||
    template<typename TypeTag>
 | 
			
		||||
    void
 | 
			
		||||
    MultisegmentWell<TypeTag>::
 | 
			
		||||
    checkOperabilityUnderTHPLimitProducer(const Simulator& ebos_simulator, const WellState& /*well_state*/, DeferredLogger& deferred_logger)
 | 
			
		||||
    checkOperabilityUnderTHPLimit(const Simulator& ebos_simulator, const WellState& /*well_state*/, DeferredLogger& deferred_logger)
 | 
			
		||||
    {
 | 
			
		||||
        const auto& summaryState = ebos_simulator.vanguard().summaryState();
 | 
			
		||||
        const auto obtain_bhp = computeBhpAtThpLimitProd(ebos_simulator, summaryState, deferred_logger);
 | 
			
		||||
        const auto obtain_bhp = this->isProducer() ? computeBhpAtThpLimitProd(ebos_simulator, summaryState, deferred_logger)
 | 
			
		||||
        : computeBhpAtThpLimitInj(ebos_simulator, summaryState, deferred_logger);
 | 
			
		||||
 | 
			
		||||
        if (obtain_bhp) {
 | 
			
		||||
            this->operability_status_.can_obtain_bhp_with_thp_limit = true;
 | 
			
		||||
@@ -1300,13 +1291,20 @@ namespace Opm
 | 
			
		||||
            this->operability_status_.obey_bhp_limit_with_thp_limit = (*obtain_bhp >= bhp_limit);
 | 
			
		||||
 | 
			
		||||
            const double thp_limit = this->getTHPConstraint(summaryState);
 | 
			
		||||
            if (*obtain_bhp < thp_limit) {
 | 
			
		||||
            if (this->isProducer() && *obtain_bhp < thp_limit) {
 | 
			
		||||
                const std::string msg = " obtained bhp " + std::to_string(unit::convert::to(*obtain_bhp, unit::barsa))
 | 
			
		||||
                                        + " bars is SMALLER than thp limit "
 | 
			
		||||
                                        + std::to_string(unit::convert::to(thp_limit, unit::barsa))
 | 
			
		||||
                                        + " bars as a producer for well " + this->name();
 | 
			
		||||
                deferred_logger.debug(msg);
 | 
			
		||||
            }
 | 
			
		||||
            else if (this->isInjector() && *obtain_bhp > thp_limit) {
 | 
			
		||||
                const std::string msg = " obtained bhp " + std::to_string(unit::convert::to(*obtain_bhp, unit::barsa))
 | 
			
		||||
                                        + " bars is LARGER than thp limit "
 | 
			
		||||
                                        + std::to_string(unit::convert::to(thp_limit, unit::barsa))
 | 
			
		||||
                                        + " bars as a injector for well " + this->name();
 | 
			
		||||
                deferred_logger.debug(msg);
 | 
			
		||||
            }
 | 
			
		||||
        } else {
 | 
			
		||||
            // Shutting wells that can not find bhp value from thp
 | 
			
		||||
            // when under THP control
 | 
			
		||||
 
 | 
			
		||||
@@ -394,10 +394,10 @@ namespace Opm
 | 
			
		||||
                                 DeferredLogger& deferred_logger) const;
 | 
			
		||||
 | 
			
		||||
        // check whether the well is operable under BHP limit with current reservoir condition
 | 
			
		||||
        virtual void checkOperabilityUnderBHPLimitProducer(const WellState& well_state, const Simulator& ebos_simulator, DeferredLogger& deferred_logger) override;
 | 
			
		||||
        virtual void checkOperabilityUnderBHPLimit(const WellState& well_state, const Simulator& ebos_simulator, DeferredLogger& deferred_logger) override;
 | 
			
		||||
 | 
			
		||||
        // check whether the well is operable under THP limit with current reservoir condition
 | 
			
		||||
        virtual void checkOperabilityUnderTHPLimitProducer(const Simulator& ebos_simulator, const WellState& well_state, DeferredLogger& deferred_logger) override;
 | 
			
		||||
        virtual void checkOperabilityUnderTHPLimit(const Simulator& ebos_simulator, const WellState& well_state, DeferredLogger& deferred_logger) override;
 | 
			
		||||
 | 
			
		||||
        // updating the inflow based on the current reservoir condition
 | 
			
		||||
        virtual void updateIPR(const Simulator& ebos_simulator, DeferredLogger& deferred_logger) const override;
 | 
			
		||||
 
 | 
			
		||||
@@ -952,12 +952,6 @@ namespace Opm
 | 
			
		||||
    {
 | 
			
		||||
        // TODO: not handling solvent related here for now
 | 
			
		||||
 | 
			
		||||
        // TODO: it only handles the producers for now
 | 
			
		||||
        // the formular for the injectors are not formulated yet
 | 
			
		||||
        if (this->isInjector()) {
 | 
			
		||||
            return;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        // initialize all the values to be zero to begin with
 | 
			
		||||
        std::fill(this->ipr_a_.begin(), this->ipr_a_.end(), 0.);
 | 
			
		||||
        std::fill(this->ipr_b_.begin(), this->ipr_b_.end(), 0.);
 | 
			
		||||
@@ -990,9 +984,9 @@ namespace Opm
 | 
			
		||||
            // Let us add a check, since the pressure is calculated based on zero value BHP
 | 
			
		||||
            // it should not be negative anyway. If it is negative, we might need to re-formulate
 | 
			
		||||
            // to taking into consideration the crossflow here.
 | 
			
		||||
            if (pressure_diff <= 0.) {
 | 
			
		||||
                deferred_logger.warning("NON_POSITIVE_DRAWDOWN_IPR",
 | 
			
		||||
                                "non-positive drawdown found when updateIPR for well " + name());
 | 
			
		||||
            if ( (this->isProducer() && pressure_diff < 0.) || (this->isInjector() && pressure_diff > 0.) ) {
 | 
			
		||||
                deferred_logger.debug("CROSSFLOW_IPR",
 | 
			
		||||
                                "cross flow found when updateIPR for well " + name());
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            // the well index associated with the connection
 | 
			
		||||
@@ -1043,7 +1037,7 @@ namespace Opm
 | 
			
		||||
    template<typename TypeTag>
 | 
			
		||||
    void
 | 
			
		||||
    StandardWell<TypeTag>::
 | 
			
		||||
    checkOperabilityUnderBHPLimitProducer(const WellState& well_state, const Simulator& ebos_simulator, DeferredLogger& deferred_logger)
 | 
			
		||||
    checkOperabilityUnderBHPLimit(const WellState& well_state, const Simulator& ebos_simulator, DeferredLogger& deferred_logger)
 | 
			
		||||
    {
 | 
			
		||||
        const auto& summaryState = ebos_simulator.vanguard().summaryState();
 | 
			
		||||
        const double bhp_limit = this->mostStrictBhpFromBhpLimits(summaryState);
 | 
			
		||||
@@ -1055,8 +1049,8 @@ namespace Opm
 | 
			
		||||
            // we need to check the BHP limit
 | 
			
		||||
 | 
			
		||||
            for (int p = 0; p < this->number_of_phases_; ++p) {
 | 
			
		||||
                const double temp = this->ipr_a_[p] - this->ipr_b_[p] * bhp_limit;
 | 
			
		||||
                if (temp < 0.) {
 | 
			
		||||
                const double ipr_rate = this->ipr_a_[p] - this->ipr_b_[p] * bhp_limit;
 | 
			
		||||
                if ( (this->isProducer() && ipr_rate < 0.) || (this->isInjector() && ipr_rate > 0.) ) {
 | 
			
		||||
                    this->operability_status_.operable_under_only_bhp_limit = false;
 | 
			
		||||
                    break;
 | 
			
		||||
                }
 | 
			
		||||
@@ -1072,8 +1066,7 @@ namespace Opm
 | 
			
		||||
 | 
			
		||||
                const double thp = this->calculateThpFromBhp(well_state, well_rates_bhp_limit, bhp_limit, deferred_logger);
 | 
			
		||||
                const double thp_limit = this->getTHPConstraint(summaryState);
 | 
			
		||||
 | 
			
		||||
                if (thp < thp_limit) {
 | 
			
		||||
                if ( (this->isProducer() && thp < thp_limit) || (this->isInjector() && thp > thp_limit) ) {
 | 
			
		||||
                    this->operability_status_.obey_thp_limit_under_bhp_limit = false;
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
@@ -1097,10 +1090,11 @@ namespace Opm
 | 
			
		||||
    template<typename TypeTag>
 | 
			
		||||
    void
 | 
			
		||||
    StandardWell<TypeTag>::
 | 
			
		||||
    checkOperabilityUnderTHPLimitProducer(const Simulator& ebos_simulator, const WellState& well_state, DeferredLogger& deferred_logger)
 | 
			
		||||
    checkOperabilityUnderTHPLimit(const Simulator& ebos_simulator, const WellState& well_state, DeferredLogger& deferred_logger)
 | 
			
		||||
    {
 | 
			
		||||
        const auto& summaryState = ebos_simulator.vanguard().summaryState();
 | 
			
		||||
        const auto obtain_bhp = computeBhpAtThpLimitProd(well_state, ebos_simulator, summaryState, deferred_logger);
 | 
			
		||||
        const auto obtain_bhp = this->isProducer() ? computeBhpAtThpLimitProd(well_state, ebos_simulator, summaryState, deferred_logger)
 | 
			
		||||
        : computeBhpAtThpLimitInj(ebos_simulator, summaryState, deferred_logger);
 | 
			
		||||
 | 
			
		||||
        if (obtain_bhp) {
 | 
			
		||||
            this->operability_status_.can_obtain_bhp_with_thp_limit = true;
 | 
			
		||||
@@ -1109,13 +1103,20 @@ namespace Opm
 | 
			
		||||
            this->operability_status_.obey_bhp_limit_with_thp_limit = (*obtain_bhp >= bhp_limit);
 | 
			
		||||
 | 
			
		||||
            const double thp_limit = this->getTHPConstraint(summaryState);
 | 
			
		||||
            if (*obtain_bhp < thp_limit) {
 | 
			
		||||
            if (this->isProducer() && *obtain_bhp < thp_limit) {
 | 
			
		||||
                const std::string msg = " obtained bhp " + std::to_string(unit::convert::to(*obtain_bhp, unit::barsa))
 | 
			
		||||
                                        + " bars is SMALLER than thp limit "
 | 
			
		||||
                                        + std::to_string(unit::convert::to(thp_limit, unit::barsa))
 | 
			
		||||
                                        + " bars as a producer for well " + name();
 | 
			
		||||
                deferred_logger.debug(msg);
 | 
			
		||||
            }
 | 
			
		||||
            else if (this->isInjector() && *obtain_bhp > thp_limit) {
 | 
			
		||||
                const std::string msg = " obtained bhp " + std::to_string(unit::convert::to(*obtain_bhp, unit::barsa))
 | 
			
		||||
                                        + " bars is LARGER than thp limit "
 | 
			
		||||
                                        + std::to_string(unit::convert::to(thp_limit, unit::barsa))
 | 
			
		||||
                                        + " bars as a injector for well " + name();
 | 
			
		||||
                deferred_logger.debug(msg);
 | 
			
		||||
            }
 | 
			
		||||
        } else {
 | 
			
		||||
            this->operability_status_.can_obtain_bhp_with_thp_limit = false;
 | 
			
		||||
            this->operability_status_.obey_bhp_limit_with_thp_limit = false;
 | 
			
		||||
 
 | 
			
		||||
@@ -299,10 +299,10 @@ protected:
 | 
			
		||||
    std::vector<double> initialWellRateFractions(const Simulator& ebosSimulator, const WellState& well_state) const;
 | 
			
		||||
 | 
			
		||||
    // check whether the well is operable under BHP limit with current reservoir condition
 | 
			
		||||
    virtual void checkOperabilityUnderBHPLimitProducer(const WellState& well_state, const Simulator& ebos_simulator, DeferredLogger& deferred_logger) =0;
 | 
			
		||||
    virtual void checkOperabilityUnderBHPLimit(const WellState& well_state, const Simulator& ebos_simulator, DeferredLogger& deferred_logger) =0;
 | 
			
		||||
 | 
			
		||||
    // check whether the well is operable under THP limit with current reservoir condition
 | 
			
		||||
    virtual void checkOperabilityUnderTHPLimitProducer(const Simulator& ebos_simulator, const WellState& well_state, DeferredLogger& deferred_logger) =0;
 | 
			
		||||
    virtual void checkOperabilityUnderTHPLimit(const Simulator& ebos_simulator, const WellState& well_state, DeferredLogger& deferred_logger) =0;
 | 
			
		||||
 | 
			
		||||
    virtual void updateIPR(const Simulator& ebos_simulator, DeferredLogger& deferred_logger) const=0;
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -812,11 +812,6 @@ updateWellTestState(const SingleWellState& ws,
 | 
			
		||||
                    DeferredLogger& deferred_logger) const
 | 
			
		||||
{
 | 
			
		||||
 | 
			
		||||
    // currently, we only updateWellTestState for producers
 | 
			
		||||
    if (this->isInjector()) {
 | 
			
		||||
        return;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // Based on current understanding, only under prediction mode, we need to shut well due to various
 | 
			
		||||
    // reasons or limits. With more knowlage or testing cases later, this might need to be corrected.
 | 
			
		||||
    if (!underPredictionMode() ) {
 | 
			
		||||
@@ -897,7 +892,6 @@ checkMaxRatioLimitWell(const SingleWellState& ws,
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    const double well_ratio = ratioFunc(well_rates, phaseUsage());
 | 
			
		||||
 | 
			
		||||
    return (well_ratio > max_ratio_limit);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -551,11 +551,6 @@ namespace Opm
 | 
			
		||||
            return;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        // focusing on PRODUCER for now
 | 
			
		||||
        if (this->isInjector()) {
 | 
			
		||||
            return;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if (!this->underPredictionMode() ) {
 | 
			
		||||
            return;
 | 
			
		||||
        }
 | 
			
		||||
@@ -575,7 +570,7 @@ namespace Opm
 | 
			
		||||
    {
 | 
			
		||||
        bool shut_unsolvable_wells = param_.shut_unsolvable_wells_;
 | 
			
		||||
        // the well operability system currently works only for producers in prediction mode
 | 
			
		||||
        return shut_unsolvable_wells && !this->isInjector() && this->underPredictionMode();
 | 
			
		||||
        return shut_unsolvable_wells && this->underPredictionMode();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@@ -591,16 +586,20 @@ namespace Opm
 | 
			
		||||
    {
 | 
			
		||||
        this->operability_status_.resetOperability();
 | 
			
		||||
 | 
			
		||||
        auto current_control = well_state.well(this->index_of_well_).production_cmode;
 | 
			
		||||
        bool thp_controled = this->isInjector() ? well_state.well(this->index_of_well_).injection_cmode == Well::InjectorCMode::THP:
 | 
			
		||||
                                              well_state.well(this->index_of_well_).production_cmode == Well::ProducerCMode::THP;
 | 
			
		||||
        bool bhp_controled = this->isInjector() ? well_state.well(this->index_of_well_).injection_cmode == Well::InjectorCMode::BHP:
 | 
			
		||||
                                              well_state.well(this->index_of_well_).production_cmode == Well::ProducerCMode::BHP;
 | 
			
		||||
 | 
			
		||||
        // Operability checking is not free
 | 
			
		||||
        // Only check wells under BHP and THP control
 | 
			
		||||
        if(current_control == Well::ProducerCMode::BHP || current_control == Well::ProducerCMode::THP) {
 | 
			
		||||
        if(bhp_controled || thp_controled) {
 | 
			
		||||
            updateIPR(ebos_simulator, deferred_logger);
 | 
			
		||||
            checkOperabilityUnderBHPLimitProducer(well_state, ebos_simulator, deferred_logger);
 | 
			
		||||
            checkOperabilityUnderBHPLimit(well_state, ebos_simulator, deferred_logger);
 | 
			
		||||
        }
 | 
			
		||||
        // we do some extra checking for wells under THP control.
 | 
			
		||||
        if (current_control == Well::ProducerCMode::THP) {
 | 
			
		||||
            checkOperabilityUnderTHPLimitProducer(ebos_simulator, well_state, deferred_logger);
 | 
			
		||||
        if (thp_controled) {
 | 
			
		||||
            checkOperabilityUnderTHPLimit(ebos_simulator, well_state, deferred_logger);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user