/* Copyright 2017 SINTEF Digital, Mathematics and Cybernetics. Copyright 2017 Statoil ASA. Copyright 2016 - 2017 IRIS AS. 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_STANDARDWELL_GENERIC_HEADER_INCLUDED #define OPM_STANDARDWELL_GENERIC_HEADER_INCLUDED #include #include #include #include #include #include #include namespace Opm { class ConvergenceReport; class DeferredLogger; class ParallelWellInfo; class Schedule; class SummaryState; class WellInterfaceGeneric; class WellState; template class StandardWellGeneric { protected: // sparsity pattern for the matrices //[A C^T [x = [ res // B D ] x_well] res_well] // the vector type for the res_well and x_well using VectorBlockWellType = Dune::DynamicVector; using BVectorWell = Dune::BlockVector; // the matrix type for the diagonal matrix D using DiagMatrixBlockWellType = Dune::DynamicMatrix; using DiagMatWell = Dune::BCRSMatrix; // the matrix type for the non-diagonal matrix B and C^T using OffDiagMatrixBlockWellType = Dune::DynamicMatrix; using OffDiagMatWell = Dune::BCRSMatrix; public: #if HAVE_CUDA || HAVE_OPENCL /// get the number of blocks of the C and B matrices, used to allocate memory in a WellContributions object void getNumBlocks(unsigned int& _nnzs) const; #endif protected: StandardWellGeneric(int Bhp, const WellInterfaceGeneric& baseif); // calculate a relaxation factor to avoid overshoot of total rates static double relaxationFactorRate(const std::vector& primary_variables, const BVectorWell& dwells); // relaxation factor considering only one fraction value static double relaxationFactorFraction(const double old_value, const double dx); double calculateThpFromBhp(const WellState& well_state, const std::vector& rates, const double bhp, DeferredLogger& deferred_logger) const; // checking the convergence of the well control equations void checkConvergenceControlEq(const WellState& well_state, ConvergenceReport& report, DeferredLogger& deferred_logger, const double max_residual_allowed) const; void checkConvergencePolyMW(const std::vector& res, ConvergenceReport& report, const double maxResidualAllowed) const; void computeConnectionPressureDelta(); std::optional computeBhpAtThpLimitInj(const std::function(const double)>& frates, const SummaryState& summary_state, DeferredLogger& deferred_logger) const; std::optional computeBhpAtThpLimitProdWithAlq(const std::function(const double)>& frates, const SummaryState& summary_state, DeferredLogger& deferred_logger, double maxPerfPress, double alq_value) const; // Base interface reference const WellInterfaceGeneric& baseif_; // residuals of the well equations BVectorWell resWell_; // densities of the fluid in each perforation std::vector perf_densities_; // pressure drop between different perforations std::vector perf_pressure_diffs_; // two off-diagonal matrices OffDiagMatWell duneB_; OffDiagMatWell duneC_; // diagonal matrix for the well DiagMatWell invDuneD_; DiagMatWell duneD_; // Wrapper for the parallel application of B for distributed wells wellhelpers::ParallelStandardWellB parallelB_; // several vector used in the matrix calculation mutable BVectorWell Bx_; mutable BVectorWell invDrw_; double getRho() const { return perf_densities_[0]; } private: int Bhp_; // index of Bhp }; } #endif // OPM_STANDARDWELL_GENERIC_HEADER_INCLUDED