My Project
StandardWellEval.hpp
1 /*
2  Copyright 2017 SINTEF Digital, Mathematics and Cybernetics.
3  Copyright 2017 Statoil ASA.
4  Copyright 2016 - 2017 IRIS AS.
5 
6  This file is part of the Open Porous Media project (OPM).
7 
8  OPM is free software: you can redistribute it and/or modify
9  it under the terms of the GNU General Public License as published by
10  the Free Software Foundation, either version 3 of the License, or
11  (at your option) any later version.
12 
13  OPM is distributed in the hope that it will be useful,
14  but WITHOUT ANY WARRANTY; without even the implied warranty of
15  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16  GNU General Public License for more details.
17 
18  You should have received a copy of the GNU General Public License
19  along with OPM. If not, see <http://www.gnu.org/licenses/>.
20 */
21 
22 
23 #ifndef OPM_STANDARDWELL_EVAL_HEADER_INCLUDED
24 #define OPM_STANDARDWELL_EVAL_HEADER_INCLUDED
25 
26 #include <opm/simulators/wells/StandardWellGeneric.hpp>
27 
28 #include <opm/material/densead/DynamicEvaluation.hpp>
29 
30 #include <optional>
31 #include <vector>
32 
33 namespace Opm
34 {
35 
36 class ConvergenceReport;
37 class DeferredLogger;
38 class GroupState;
39 class Schedule;
40 class SummaryState;
41 class WellContributions;
42 template<class FluidSystem, class Indices, class Scalar> class WellInterfaceIndices;
43 class WellState;
44 
45 template<class FluidSystem, class Indices, class Scalar>
46 class StandardWellEval : public StandardWellGeneric<Scalar>
47 {
48 protected:
49  // number of the conservation equations
50  static constexpr int numWellConservationEq = Indices::numPhases + Indices::numSolvents;
51  // number of the well control equations
52  static constexpr int numWellControlEq = 1;
53  // number of the well equations that will always be used
54  // based on the solution strategy, there might be other well equations be introduced
55  static constexpr int numStaticWellEq = numWellConservationEq + numWellControlEq;
56  // the index for Bhp in primary variables and also the index of well control equation
57  // they both will be the last one in their respective system.
58  // TODO: we should have indices for the well equations and well primary variables separately
59  static constexpr int Bhp = numStaticWellEq - numWellControlEq;
60 
61  // the positions of the primary variables for StandardWell
62  // the first one is the weighted total rate (WQ_t), the second and the third ones are F_w and F_g,
63  // which represent the fraction of Water and Gas based on the weighted total rate, the last one is BHP.
64  // correspondingly, we have four well equations for blackoil model, the first three are mass
65  // converstation equations, and the last one is the well control equation.
66  // primary variables related to other components, will be before the Bhp and after F_g.
67  // well control equation is always the last well equation.
68  // TODO: in the current implementation, we use the well rate as the first primary variables for injectors,
69  // instead of G_t.
70 
71  // Table showing the primary variable indices, depending on what phases are present:
72  //
73  // WOG OG WG WO W/O/G (single phase)
74  // GTotal 0 0 0 0 0
75  // WFrac 1 -1000 -1000 1 -1000
76  // GFrac 2 1 1 -1000 -1000
77  // Spres 3 2 2 2 1
78 
79  static const int WQTotal = 0;
80  // In the implementation, one should use has_wfrac_variable
81  // rather than has_water to check if you should do something
82  // with the variable at the WFrac location, similar for GFrac.
83  // (following implementation MultisegmentWellEval.hpp)
84  static const bool waterEnabled = Indices::waterEnabled;
85  static const bool gasEnabled = Indices::gasEnabled;
86  static const bool oilEnabled = Indices::oilEnabled;
87 
88  static constexpr bool has_wfrac_variable = Indices::waterEnabled && Indices::oilEnabled;
89  static constexpr bool has_gfrac_variable = Indices::gasEnabled && Indices::numPhases > 1;
90  static constexpr int WFrac = has_wfrac_variable ? 1 : -1000;
91  static constexpr int GFrac = has_gfrac_variable ? has_wfrac_variable + 1 : -1000;
92  static constexpr int SFrac = !Indices::enableSolvent ? -1000 : 3;
93 
94 public:
95  using EvalWell = DenseAd::DynamicEvaluation<Scalar, numStaticWellEq + Indices::numEq + 1>;
96  using Eval = DenseAd::Evaluation<Scalar, Indices::numEq>;
97  using BVectorWell = typename StandardWellGeneric<Scalar>::BVectorWell;
98 
99 #if HAVE_CUDA || HAVE_OPENCL
101  void addWellContribution(WellContributions& wellContribs) const;
102 #endif
103 
104 protected:
106 
108 
109  void initPrimaryVariablesEvaluation() const;
110 
111  const EvalWell& getBhp() const
112  {
113  return primary_variables_evaluation_[Bhp];
114  }
115 
116  const EvalWell& getWQTotal() const
117  {
118  return primary_variables_evaluation_[WQTotal];
119  }
120 
121  EvalWell extendEval(const Eval& in) const;
122  EvalWell getQs(const int compIdx) const;
123  EvalWell wellSurfaceVolumeFraction(const int compIdx) const;
124  EvalWell wellVolumeFraction(const unsigned compIdx) const;
125  EvalWell wellVolumeFractionScaled(const int phase) const;
126 
127  // calculate a relaxation factor to avoid overshoot of the fractions for producers
128  // which might result in negative rates
129  static double relaxationFactorFractionsProducer(const std::vector<double>& primary_variables,
130  const BVectorWell& dwells);
131 
132  void assembleControlEq(const WellState& well_state,
133  const GroupState& group_state,
134  const Schedule& schedule,
135  const SummaryState& summaryState,
136  DeferredLogger& deferred_logger);
137 
138  // computing the accumulation term for later use in well mass equations
139  void computeAccumWell();
140 
141  // TODO: not total sure whether it is a good idea to put this function here
142  // the major reason to put here is to avoid the usage of Wells struct
143  void computeConnectionDensities(const std::vector<double>& perfComponentRates,
144  const std::vector<double>& b_perf,
145  const std::vector<double>& rsmax_perf,
146  const std::vector<double>& rvmax_perf,
147  const std::vector<double>& surf_dens_perf,
148  DeferredLogger& deferred_logger);
149 
150  ConvergenceReport getWellConvergence(const WellState& well_state,
151  const std::vector<double>& B_avg,
152  const double maxResidualAllowed,
153  const double tol_wells,
154  const double relaxed_tolerance_flow,
155  const bool relax_tolerance,
156  std::vector<double>& res,
157  DeferredLogger& deferred_logger) const;
158 
159  void init(std::vector<double>& perf_depth,
160  const std::vector<double>& depth_arg,
161  const int num_cells,
162  const bool has_polymermw);
163 
164  // handle the non reasonable fractions due to numerical overshoot
165  void processFractions() const;
166 
167  void updatePrimaryVariables(const WellState& well_state,
168  DeferredLogger& deferred_logger) const;
169 
170  void updatePrimaryVariablesPolyMW(const BVectorWell& dwells) const;
171 
172  void updateWellStateFromPrimaryVariables(WellState& well_state,
173  DeferredLogger& deferred_logger) const;
174 
175  void updatePrimaryVariablesNewton(const BVectorWell& dwells,
176  const double dFLimit,
177  const double dBHPLimit) const;
178 
179  void updateWellStateFromPrimaryVariablesPolyMW(WellState& well_state) const;
180 
181  void updateThp(WellState& well_state,
182  DeferredLogger& deferred_logger) const;
183 
184  // total number of the well equations and primary variables
185  // there might be extra equations be used, numWellEq will be updated during the initialization
186  int numWellEq_ = numStaticWellEq;
187 
188  // the values for the primary varibles
189  // based on different solutioin strategies, the wells can have different primary variables
190  mutable std::vector<double> primary_variables_;
191 
192  // the Evaluation for the well primary variables, which contain derivativles and are used in AD calculation
193  mutable std::vector<EvalWell> primary_variables_evaluation_;
194 
195  // the saturations in the well bore under surface conditions at the beginning of the time step
196  std::vector<double> F0_;
197 };
198 
199 }
200 
201 #endif // OPM_STANDARDWELL_EVAL_HEADER_INCLUDED
Represents the convergence status of the whole simulator, to make it possible to query and store the ...
Definition: ConvergenceReport.hpp:36
Definition: DeferredLogger.hpp:57
Definition: GroupState.hpp:34
Definition: StandardWellEval.hpp:47
Definition: StandardWellGeneric.hpp:49
This class serves to eliminate the need to include the WellContributions into the matrix (with –matri...
Definition: WellContributions.hpp:53
Definition: WellInterfaceIndices.hpp:35
The state of a set of wells, tailored for use by the fully implicit blackoil simulator.
Definition: WellState.hpp:56
This file contains a set of helper functions used by VFPProd / VFPInj.
Definition: BlackoilPhases.hpp:27