Files
opm-simulators/opm/simulators/wells/StandardWellGeneric.hpp
Håkon Hægland 4970b0641e Improve debugging tools in gaslift code.
Introduces a gaslift debugging variable in ALQState in WellState. This
variable will persist between timesteps in contrast to when debugging
variables are defined in GasLiftSingleWell, GasLiftGroupState, or GasLiftStage2.

Currently only an integer variable debug_counter is added to ALQState,
which can be used as follows: First debugging is switched on globally
for BlackOilWellModel, GasLiftSingleWell, GasLiftGroupState, and
GasLiftStage2 by setting glift_debug to a true value in BlackOilWellModelGeneric.
Then, the following debugging code can be added to e.g. one of
GasLiftSingleWell, GasLiftGroupState, or GasLiftStage2 :

    auto count = debugUpdateGlobalCounter_();
    if (count == some_integer) {
        displayDebugMessage_("stop here");
    }

Here, the integer "some_integer" is determined typically by looking at
the debugging output of a previous run. This can be done since the
call to debugUpdateGlobalCounter_() will print out the current value
of the counter and then increment the counter by one. And it will be
easy to recognize these values in the debug ouput. If you find a place
in the output that looks suspect, just take a note of the counter
value in the output around that point and insert the value for
"some_integer", then after recompiling the code with the desired value
for "some_integer", it is now easy to set a breakpoint in GDB at the
line

    displayDebugMessage_("stop here").

shown in the above snippet. This should improve the ability to quickly
to set a breakpoint in GDB around at a given time and point in the simulation.
2022-01-23 20:37:26 +01:00

143 lines
5.0 KiB
C++

/*
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 <http://www.gnu.org/licenses/>.
*/
#ifndef OPM_STANDARDWELL_GENERIC_HEADER_INCLUDED
#define OPM_STANDARDWELL_GENERIC_HEADER_INCLUDED
#include <dune/common/dynmatrix.hh>
#include <dune/common/dynvector.hh>
#include <dune/istl/bcrsmatrix.hh>
#include <dune/istl/bvector.hh>
#include <opm/simulators/wells/WellHelpers.hpp>
#include <optional>
#include <vector>
namespace Opm
{
class ConvergenceReport;
class DeferredLogger;
class ParallelWellInfo;
class Schedule;
class SummaryState;
class WellInterfaceGeneric;
class WellState;
template<class Scalar>
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<Scalar>;
using BVectorWell = Dune::BlockVector<VectorBlockWellType>;
// the matrix type for the diagonal matrix D
using DiagMatrixBlockWellType = Dune::DynamicMatrix<Scalar>;
using DiagMatWell = Dune::BCRSMatrix<DiagMatrixBlockWellType>;
// the matrix type for the non-diagonal matrix B and C^T
using OffDiagMatrixBlockWellType = Dune::DynamicMatrix<Scalar>;
using OffDiagMatWell = Dune::BCRSMatrix<OffDiagMatrixBlockWellType>;
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<double>& 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<double>& 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<double>& res,
ConvergenceReport& report,
const double maxResidualAllowed) const;
void computeConnectionPressureDelta();
std::optional<double> computeBhpAtThpLimitInj(const std::function<std::vector<double>(const double)>& frates,
const SummaryState& summary_state,
DeferredLogger& deferred_logger) const;
std::optional<double> computeBhpAtThpLimitProdWithAlq(const std::function<std::vector<double>(const double)>& frates,
const SummaryState& summary_state,
DeferredLogger& deferred_logger,
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<double> perf_densities_;
// pressure drop between different perforations
std::vector<double> perf_pressure_diffs_;
// two off-diagonal matrices
OffDiagMatWell duneB_;
OffDiagMatWell duneC_;
// diagonal matrix for the well
DiagMatWell invDuneD_;
// Wrapper for the parallel application of B for distributed wells
wellhelpers::ParallelStandardWellB<Scalar> 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