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  // WQTotal 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 
100  void addWellContribution(WellContributions& wellContribs) const;
101 
102 protected:
104 
106 
107  void initPrimaryVariablesEvaluation() const;
108 
109  const EvalWell& getBhp() const
110  {
111  return primary_variables_evaluation_[Bhp];
112  }
113 
114  const EvalWell& getWQTotal() const
115  {
116  return primary_variables_evaluation_[WQTotal];
117  }
118 
119  EvalWell extendEval(const Eval& in) const;
120  EvalWell getQs(const int compIdx) const;
121  EvalWell wellSurfaceVolumeFraction(const int compIdx) const;
122  EvalWell wellVolumeFraction(const unsigned compIdx) const;
123  EvalWell wellVolumeFractionScaled(const int phase) const;
124 
125  // calculate a relaxation factor to avoid overshoot of the fractions for producers
126  // which might result in negative rates
127  static double relaxationFactorFractionsProducer(const std::vector<double>& primary_variables,
128  const BVectorWell& dwells);
129 
130  void assembleControlEq(const WellState& well_state,
131  const GroupState& group_state,
132  const Schedule& schedule,
133  const SummaryState& summaryState,
134  DeferredLogger& deferred_logger);
135 
136  // computing the accumulation term for later use in well mass equations
137  void computeAccumWell();
138 
139  // TODO: not total sure whether it is a good idea to put this function here
140  // the major reason to put here is to avoid the usage of Wells struct
141  void computeConnectionDensities(const std::vector<double>& perfComponentRates,
142  const std::vector<double>& b_perf,
143  const std::vector<double>& rsmax_perf,
144  const std::vector<double>& rvmax_perf,
145  const std::vector<double>& rvwmax_perf,
146  const std::vector<double>& surf_dens_perf,
147  DeferredLogger& deferred_logger);
148 
149  ConvergenceReport getWellConvergence(const WellState& well_state,
150  const std::vector<double>& B_avg,
151  const double maxResidualAllowed,
152  const double tol_wells,
153  const double relaxed_tolerance_flow,
154  const bool relax_tolerance,
155  std::vector<double>& res,
156  DeferredLogger& deferred_logger) const;
157 
158  void init(std::vector<double>& perf_depth,
159  const std::vector<double>& depth_arg,
160  const int num_cells,
161  const bool has_polymermw);
162 
163  // handle the non reasonable fractions due to numerical overshoot
164  void processFractions() const;
165 
166  void updatePrimaryVariables(const WellState& well_state,
167  DeferredLogger& deferred_logger) const;
168 
169  void updatePrimaryVariablesPolyMW(const BVectorWell& dwells) const;
170 
171  void updateWellStateFromPrimaryVariables(WellState& well_state,
172  DeferredLogger& deferred_logger) const;
173 
174  void updatePrimaryVariablesNewton(const BVectorWell& dwells,
175  const double dFLimit,
176  const double dBHPLimit) const;
177 
178  void updateWellStateFromPrimaryVariablesPolyMW(WellState& well_state) const;
179 
180  void updateThp(WellState& well_state,
181  DeferredLogger& deferred_logger) const;
182 
183  // total number of the well equations and primary variables
184  // there might be extra equations be used, numWellEq will be updated during the initialization
185  int numWellEq_ = numStaticWellEq;
186 
187  // the values for the primary varibles
188  // based on different solutioin strategies, the wells can have different primary variables
189  mutable std::vector<double> primary_variables_;
190 
191  // the Evaluation for the well primary variables, which contain derivativles and are used in AD calculation
192  mutable std::vector<EvalWell> primary_variables_evaluation_;
193 
194  // the saturations in the well bore under surface conditions at the beginning of the time step
195  std::vector<double> F0_;
196 };
197 
198 }
199 
200 #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
void addWellContribution(WellContributions &wellContribs) const
add the contribution (C, D^-1, B matrices) of this Well to the WellContributions object
Definition: StandardWellEval.cpp:1120
Definition: StandardWellGeneric.hpp:50
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