/* Copyright 2017 SINTEF Digital, Mathematics and Cybernetics. Copyright 2017 Statoil ASA. Copyright 2017 IRIS Copyright 2019 Norce This file is part of the Open Porous Media project (OPM). OPM is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. OPM is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with OPM. If not, see . */ #ifndef OPM_WELL_BPH_THP_CALCULATOR_HEADER_INCLUDED #define OPM_WELL_BPH_THP_CALCULATOR_HEADER_INCLUDED #include #include #include namespace Opm { class DeferredLogger; class SummaryState; class Well; template class WellInterfaceGeneric; template class WellState; //! \brief Class for computing BHP limits. template class WellBhpThpCalculator { public: //! \brief Constructor sets reference to well. WellBhpThpCalculator(const WellInterfaceGeneric& well) : well_(well) {} //! \brief Checks if well has THP constraints. bool wellHasTHPConstraints(const SummaryState& summaryState) const; //! \brief Get THP constraint for well. Scalar getTHPConstraint(const SummaryState& summaryState) const; //! \brief Obtain the most strict BHP from BHP limits. Scalar mostStrictBhpFromBhpLimits(const SummaryState& summaryState) const; //! \brief Calculates THP from BHP. Scalar calculateThpFromBhp(const std::vector& rates, const Scalar bhp, const Scalar rho, const std::optional& alq, const Scalar thp_limit, DeferredLogger& deferred_logger) const; //! \brief Compute BHP from THP limit for a producer. std::optional computeBhpAtThpLimitProd(const std::function(const Scalar)>& frates, const SummaryState& summary_state, const Scalar maxPerfPress, const Scalar rho, const Scalar alq_value, const Scalar thp_limit, DeferredLogger& deferred_logger) const; //! \brief Compute BHP from THP limit for an injector. std::optional computeBhpAtThpLimitInj(const std::function(const Scalar)>& frates, const SummaryState& summary_state, const Scalar rho, const Scalar flo_rel_tol, const int max_iteration, const bool throwOnError, DeferredLogger& deferred_logger) const; //! \brief Update THP. void updateThp(const Scalar rho, const std::function& alq_value, const std::array& active, WellState& well_state, const SummaryState& summary_state, DeferredLogger& deferred_logger) const; template EvalWell calculateBhpFromThp(const WellState& well_state, const std::vector& rates, const Well& well, const SummaryState& summaryState, const Scalar rho, DeferredLogger& deferred_logger) const; Scalar calculateMinimumBhpFromThp(const WellState& well_state, const Well& well, const SummaryState& summaryState, const Scalar rho) const; bool isStableSolution(const WellState& well_state, const Well& well, const std::vector& rates, const SummaryState& summaryState) const; std::optional estimateStableBhp (const WellState& well_state, const Well& well, const std::vector& rates, const Scalar rho, const SummaryState& summaryState) const; std::pair getFloIPR(const WellState& well_state, const Well& well, const SummaryState& summary_state) const; //! \brief Find limits using brute-force solver. static bool bruteForceBracketCommonTHP(const std::function& eq, const std::array& range, Scalar& low, Scalar& high, std::optional& approximate_solution, const Scalar& limit, DeferredLogger& deferred_logger); //! \brief Find limits using brute-force solver. static bool bruteForceBracketCommonTHP(const std::function& eq, Scalar& min_thp, Scalar& max_thp); private: //! \brief Compute BHP from THP limit for an injector - implementation. template std::optional computeBhpAtThpLimitInjImpl(const std::function(const Scalar)>& frates, const SummaryState& summary_state, const Scalar rho, const Scalar flo_rel_tol, const int max_iteration, DeferredLogger& deferred_logger) const; //! \brief Calculate max BHP. std::optional bhpMax(const std::function& fflo, const Scalar bhp_limit, const Scalar maxPerfPress, const Scalar vfp_flo_front, DeferredLogger& deferred_logger) const; //! \brief Common code for finding BHP from THP limit for producers/injectors. std::optional computeBhpAtThpLimit(const std::function(const Scalar)>& frates, const std::function)>& fbhp, const std::array& range, DeferredLogger& deferred_logger) const; //! \brief Get pressure adjustment to the bhp calculated from VFP table Scalar getVfpBhpAdjustment(const Scalar bph_tab, const Scalar thp_limit) const; //! \brief Find limits using bisection. bool bisectBracket(const std::function& eq, const std::array& range, Scalar& low, Scalar& high, std::optional& approximate_solution, DeferredLogger& deferred_logger) const; //! \brief Find limits using brute-force solver. static bool bruteForceBracket(const std::function& eq, const std::array& range, Scalar& low, Scalar& high, DeferredLogger& deferred_logger); Scalar findThpFromBhpIteratively(const std::function& thp_func, const Scalar bhp, const Scalar thp_limit, const Scalar dp, DeferredLogger& deferred_logger) const; const WellInterfaceGeneric& well_; //!< Reference to well interface }; } #endif // OPM_WELL_BHP_THP_CALCULATOR_HEADER_INCLUDED