opm-simulators
MultisegmentWellPrimaryVariables.hpp
1 /*
2  Copyright 2017 SINTEF Digital, Mathematics and Cybernetics.
3  Copyright 2017 Statoil ASA.
4 
5  This file is part of the Open Porous Media project (OPM).
6 
7  OPM is free software: you can redistribute it and/or modify
8  it under the terms of the GNU General Public License as published by
9  the Free Software Foundation, either version 3 of the License, or
10  (at your option) any later version.
11 
12  OPM is distributed in the hope that it will be useful,
13  but WITHOUT ANY WARRANTY; without even the implied warranty of
14  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15  GNU General Public License for more details.
16 
17  You should have received a copy of the GNU General Public License
18  along with OPM. If not, see <http://www.gnu.org/licenses/>.
19 */
20 
21 
22 #ifndef OPM_MULTISEGMENTWELL_PRIMARY_VARIABLES_HEADER_INCLUDED
23 #define OPM_MULTISEGMENTWELL_PRIMARY_VARIABLES_HEADER_INCLUDED
24 
25 #include <opm/material/densead/Evaluation.hpp>
26 
27 #include <opm/simulators/wells/MultisegmentWellEquations.hpp>
28 #include <opm/input/eclipse/Schedule/SummaryState.hpp>
29 #include <opm/input/eclipse/Units/Units.hpp>
30 
31 #include <array>
32 #include <cstddef>
33 #include <vector>
34 
35 namespace Opm
36 {
37 
38 class DeferredLogger;
39 template <typename Scalar, typename IndexTraits> class MultisegmentWellGeneric;
40 template<class FluidSystem, class Indices> class WellInterfaceIndices;
41 template<typename Scalar, typename IndexTraits> class WellState;
42 
43 template<class FluidSystem, class Indices>
44 class MultisegmentWellPrimaryVariables
45 {
46 public:
47  // TODO: for now, not considering the polymer, solvent and so on to simplify the development process.
48 
49  // TODO: we need to have order for the primary variables and also the order for the well equations.
50  // sometimes, they are similar, while sometimes, they can have very different forms.
51 
52  // Table showing the primary variable indices, depending on what phases are present:
53  //
54  // WQTotal 0 0 0 0 0
55  // WFrac 1 -1000 -1000 1 -1000
56  // GFrac 2 1 1 -1000 -1000
57  // Temperature(*) 3 2 2 2 1
58  // SPres 3/4 2/3 2/3 2/3 1/2
59  // (*) Temperature is only present when energy is enabled;
60  // SPres shifts by one when Temperature is present.
61 
62  static constexpr bool has_wfrac_variable = Indices::waterEnabled && Indices::oilEnabled;
63  static constexpr bool has_gfrac_variable = Indices::gasEnabled && Indices::numPhases > 1;
64  static constexpr bool enable_energy = Indices::enableFullyImplicitThermal;
65 
66  static constexpr int WQTotal = 0;
67  static constexpr int WFrac = has_wfrac_variable ? 1 : -1000;
68  static constexpr int GFrac = has_gfrac_variable ? has_wfrac_variable + 1 : -1000;
69  // Temperature comes before SPres: it is a conservation equation consistent
70  // with reservoir equations, while SPres is well-specific.
71  static constexpr int Temperature = enable_energy ? has_wfrac_variable + has_gfrac_variable + 1 : -1000;
72  static constexpr int SPres = has_wfrac_variable + has_gfrac_variable + 1 + enable_energy;
73 
74  // the number of well equations TODO: it should have a more general strategy for it
75  static constexpr int numWellEq = Indices::numPhases + 1 + enable_energy;
76 
77  using Scalar = typename FluidSystem::Scalar;
78  using IndexTraits = typename FluidSystem::IndexTraitsType;
79  using EvalWell = DenseAd::Evaluation<Scalar, /*size=*/Indices::numEq + numWellEq>;
80 
81  using Equations = MultisegmentWellEquations<Scalar,IndexTraits, numWellEq, Indices::numEq>;
82  using BVectorWell = typename Equations::BVectorWell;
83 
84  explicit MultisegmentWellPrimaryVariables(const WellInterfaceIndices<FluidSystem,Indices>& well)
85  : well_(well)
86  {}
87 
89  void resize(const int numSegments);
90 
92  void update(const WellState<Scalar, IndexTraits>& well_state,
93  const bool stop_or_zero_rate_target);
94 
96  void updateNewton(const BVectorWell& dwells,
97  const Scalar relaxation_factor,
98  const Scalar DFLimit,
99  const bool stop_or_zero_rate_target,
100  const Scalar max_pressure_change);
101 
103  void copyToWellState(const MultisegmentWellGeneric<Scalar, IndexTraits>& mswell,
104  const Scalar rho,
105  WellState<Scalar, IndexTraits>& well_state,
106  const SummaryState& summary_state,
107  DeferredLogger& deferred_logger) const;
108 
111  EvalWell volumeFractionScaled(const int seg,
112  const int compIdx) const;
113 
116  EvalWell surfaceVolumeFraction(const int seg,
117  const int compIdx) const;
118 
120  EvalWell getSegmentRateUpwinding(const int seg,
121  const int seg_upwind,
122  const int comp_idx) const;
123 
125  EvalWell getBhp() const;
126 
128  EvalWell getSegmentPressure(const int seg) const;
129 
131  EvalWell getSegmentTemperature(const int seg) const;
132 
134  EvalWell getSegmentRate(const int seg,
135  const int comp_idx) const;
136 
138  EvalWell getQs(const int comp_idx) const;
139 
141  EvalWell getWQTotal() const;
142 
144  const std::array<EvalWell, numWellEq>& eval(const int idx) const
145  { return evaluation_[idx]; }
146 
148  const std::array<Scalar, numWellEq>& value(const int idx) const
149  { return value_[idx]; }
150 
152  void setValue(const int idx, const std::array<Scalar, numWellEq>& val)
153  { value_[idx] = val; }
154 
156  void outputLowLimitPressureSegments(DeferredLogger& deferred_logger) const;
157 
159  void scaledWellFractions(std::vector<Scalar>& fractions,
160  DeferredLogger& deferred_logger) const;
161 
162 private:
164  void setEvaluationsFromValues();
165 
167  void processFractions(const int seg);
168 
170  EvalWell volumeFraction(const int seg,
171  const int compIdx) const;
172 
175  std::vector<std::array<Scalar, numWellEq>> value_;
176 
179  std::vector<std::array<EvalWell, numWellEq>> evaluation_;
180 
182 
183  static constexpr double bhp_lower_limit = 1. * unit::barsa - 1. * unit::Pascal;
184  static constexpr double seg_pres_lower_limit = 0.;
185 };
186 
187 }
188 
189 #endif // OPM_MULTISEGMENTWELL_PRIMARY_VARIABLES_HEADER_INCLUDED
EvalWell getSegmentRate(const int seg, const int comp_idx) const
Get rate for a component in a segment.
Definition: MultisegmentWellPrimaryVariables.cpp:696
const std::array< EvalWell, numWellEq > & eval(const int idx) const
Returns a const ref to an array of evaluations.
Definition: MultisegmentWellPrimaryVariables.hpp:144
void updateNewton(const BVectorWell &dwells, const Scalar relaxation_factor, const Scalar DFLimit, const bool stop_or_zero_rate_target, const Scalar max_pressure_change)
Update values from newton update vector.
Definition: MultisegmentWellPrimaryVariables.cpp:173
EvalWell getQs(const int comp_idx) const
Returns scaled rate for a component.
Definition: MultisegmentWellPrimaryVariables.cpp:705
Structs needed for tpfalinearizer and its gpuparams struct extracted to be defined in one place that ...
Definition: blackoilbioeffectsmodules.hh:45
EvalWell surfaceVolumeFraction(const int seg, const int compIdx) const
Returns surface volume fraction for a component in a segment.
Definition: MultisegmentWellPrimaryVariables.cpp:616
void scaledWellFractions(std::vector< Scalar > &fractions, DeferredLogger &deferred_logger) const
get scaled fractions of top segment.
Definition: MultisegmentWellPrimaryVariables.cpp:741
EvalWell volumeFractionScaled(const int seg, const int compIdx) const
Returns scaled volume fraction for a component in a segment.
Definition: MultisegmentWellPrimaryVariables.cpp:599
void update(const WellState< Scalar, IndexTraits > &well_state, const bool stop_or_zero_rate_target)
Copy values from well state.
Definition: MultisegmentWellPrimaryVariables.cpp:70
EvalWell getWQTotal() const
Get WQTotal.
Definition: MultisegmentWellPrimaryVariables.cpp:713
EvalWell getBhp() const
Get bottomhole pressure.
Definition: MultisegmentWellPrimaryVariables.cpp:688
void setValue(const int idx, const std::array< Scalar, numWellEq > &val)
Set a value array. Note that this does not also set the corresponding evaluation. ...
Definition: MultisegmentWellPrimaryVariables.hpp:152
Definition: MultisegmentWellAssemble.hpp:38
Definition: DeferredLogger.hpp:56
EvalWell getSegmentPressure(const int seg) const
Get pressure for a segment.
Definition: MultisegmentWellPrimaryVariables.cpp:672
EvalWell getSegmentRateUpwinding(const int seg, const int seg_upwind, const int comp_idx) const
Returns upwinding rate for a component in a segment.
Definition: MultisegmentWellPrimaryVariables.cpp:632
const std::array< Scalar, numWellEq > & value(const int idx) const
Returns a value array.
Definition: MultisegmentWellPrimaryVariables.hpp:148
void outputLowLimitPressureSegments(DeferredLogger &deferred_logger) const
output the segments with pressure close to lower pressure limit for debugging purpose ...
Definition: MultisegmentWellPrimaryVariables.cpp:721
void copyToWellState(const MultisegmentWellGeneric< Scalar, IndexTraits > &mswell, const Scalar rho, WellState< Scalar, IndexTraits > &well_state, const SummaryState &summary_state, DeferredLogger &deferred_logger) const
Copy values to well state.
Definition: MultisegmentWellPrimaryVariables.cpp:239
EvalWell getSegmentTemperature(const int seg) const
Get temperature for a segment.
Definition: MultisegmentWellPrimaryVariables.cpp:680
void resize(const int numSegments)
Resize values and evaluations.
Definition: MultisegmentWellPrimaryVariables.cpp:49