opm-simulators
MultisegmentWellSegments.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_SEGMENTS_HEADER_INCLUDED
23 #define OPM_MULTISEGMENTWELL_SEGMENTS_HEADER_INCLUDED
24 
25 #include <opm/simulators/wells/MultisegmentWellPrimaryVariables.hpp>
26 #include <opm/simulators/wells/ParallelWellInfo.hpp>
27 
28 #include <cstddef>
29 #include <vector>
30 
31 namespace Opm {
32 
33  class AutoICD;
34  template<class Scalar> class SegmentState;
35  class UnitSystem;
36  template<typename Scalar, typename IndexTraits> class WellInterfaceGeneric;
37  class SummaryState;
38 
39 } // namespace Opm
40 
41 namespace Opm {
42 
43 template<typename FluidSystem, typename Indices>
45 {
47  using Scalar = typename FluidSystem::Scalar;
48  using EvalWell = typename PrimaryVariables::EvalWell;
49  using IndexTraits = typename FluidSystem::IndexTraitsType;
50 
51 public:
52  MultisegmentWellSegments(const int numSegments,
53  const ParallelWellInfo<Scalar>& parallel_well_info,
55 
56  void computeFluidProperties(const EvalWell& temperature,
57  const EvalWell& saltConcentration,
58  const PrimaryVariables& primary_variables,
59  DeferredLogger& deferred_logger);
60 
62  void updateUpwindingSegments(const PrimaryVariables& primary_variables);
63 
64  EvalWell getHydroPressureLoss(const int seg,
65  const int seg_side) const;
66 
68  Scalar getPressureDiffSegLocalPerf(const int seg,
69  const int local_perf_index) const;
70 
71  EvalWell getSurfaceVolume(const EvalWell& temperature,
72  const EvalWell& saltConcentration,
73  const PrimaryVariables& primary_variables,
74  const int seg_idx,
75  DeferredLogger& deferred_logger) const;
76 
77  EvalWell getFrictionPressureLoss(const int seg,
78  const bool extra_reverse_flow_derivatives = false) const;
79 
80  // pressure drop for Spiral ICD segment (WSEGSICD)
81  EvalWell pressureDropSpiralICD(const int seg,
82  const bool extra_reverse_flow_derivatives = false) const;
83 
84  // pressure drop for Autonomous ICD segment (WSEGAICD)
85  EvalWell pressureDropAutoICD(const int seg,
86  const UnitSystem& unit_system,
87  const bool extra_reverse_flow_derivatives = false) const;
88 
89  // pressure drop for sub-critical valve (WSEGVALV)
90  EvalWell pressureDropValve(const int seg,
91  const SummaryState& st,
92  const bool extra_reverse_flow_derivatives = false) const;
93 
94  // pressure loss contribution due to acceleration
95  EvalWell accelerationPressureLossContribution(const int seg,
96  const Scalar area,
97  const bool extra_reverse_flow_derivatives = false) const;
98 
99  const std::vector<std::vector<int>>& inlets() const
100  {
101  return inlets_;
102  }
103 
104  const std::vector<int>& inlets(const int seg) const
105  {
106  return inlets_[seg];
107  }
108 
109  const std::vector<std::vector<int>>& perforations() const
110  {
111  return perforations_;
112  }
113 
114  int upwinding_segment(const int seg) const
115  {
116  return upwinding_segments_[seg];
117  }
118 
119  Scalar getRefDensity() const
120  {
121  return densities_[0].value();
122  }
123 
124  const EvalWell& density(const int seg) const
125  {
126  return densities_[seg];
127  }
128 
129  Scalar local_perforation_depth_diff(const int local_perf_index) const
130  {
131  return local_perforation_depth_diffs_[local_perf_index];
132  }
133 
134  void copyPhaseDensities(SegmentState<Scalar>& segSol) const;
135 
136 private:
137  // TODO: trying to use the information from the Well opm-parser as much
138  // as possible, it will possibly be re-implemented later for efficiency reason.
139 
140  // the completions that is related to each segment
141  // the completions's ids are their index in the vector well_index_, well_cell_
142  // This is also assuming the order of the completions in Well is the same with
143  // the order of the completions in wells.
144  // it is for convenience reason. we can just calculate the information for segment once
145  // then using it for all the perforations belonging to this segment
146  std::vector<std::vector<int>> perforations_;
147 
148  // depth difference between the segment and the perforation
149  // or in another way, the depth difference between the perforation and
150  // the segment the perforation belongs to
151  // This vector contains the depth differences for *all* perforations across all processes
152  // that this well lies on, its size is well.wellEcl().getConnections().size(),
153  // also it works with *global* perforation indices!
154  std::vector<Scalar> local_perforation_depth_diffs_;
155 
156  // the inlet segments for each segment. It is for convenience and efficiency reason
157  std::vector<std::vector<int>> inlets_;
158 
159  std::vector<Scalar> depth_diffs_;
160 
161  std::vector<Scalar> surface_densities_;
162 
163  // the densities of segment fluids
164  // we should not have this member variable
165  std::vector<EvalWell> densities_;
166 
167  // the mass rate of the segments
168  std::vector<EvalWell> mass_rates_;
169 
170  // the viscosity of the segments
171  std::vector<EvalWell> viscosities_;
172 
173  // the upwinding segment for each segment based on the flow direction
174  std::vector<int> upwinding_segments_;
175 
176  std::vector<std::vector<EvalWell>> phase_densities_;
177  std::vector<std::vector<EvalWell>> phase_fractions_;
178  std::vector<std::vector<EvalWell>> phase_viscosities_;
179 
181 
182  void copyPhaseDensities(const unsigned phaseIdx,
183  const std::size_t stride,
184  Scalar* dens) const;
185 
186  Scalar mixtureDensity(const int seg) const;
187  Scalar mixtureDensityWithExponents(const int seg) const;
188  Scalar mixtureDensityWithExponents(const AutoICD& aicd, const int seg) const;
189 
190  // this class is used to store the result of phase property calculation
191  struct PhaseCalcResult {
192  explicit PhaseCalcResult(const std::size_t num_quantities)
193  : b(num_quantities, 0.0)
194  , mix(num_quantities, 0.0)
195  , mix_s(num_quantities, 0.0)
196  , phase_viscosities(num_quantities, 0.0)
197  , phase_densities(num_quantities, 0.0)
198  {}
199 
200  void clear();
201 
202  std::vector<EvalWell> b;
203  std::vector<EvalWell> mix;
204  std::vector<EvalWell> mix_s;
205  std::vector<EvalWell> phase_viscosities;
206  std::vector<EvalWell> phase_densities;
207  EvalWell vol_ratio{0.};
208  };
209 
210  void calculatePhaseProperties(PhaseCalcResult& result,
211  const EvalWell& temperature,
212  const EvalWell& saltConcentration,
213  const PrimaryVariables& primary_variables,
214  int seg,
215  bool update_visc_and_den,
216  DeferredLogger& deferred_logger) const;
217 };
218 
219 } // namespace Opm
220 
221 #endif // OPM_MULTISEGMENTWELL_SEGMENTS_HEADER_INCLUDED
Scalar getPressureDiffSegLocalPerf(const int seg, const int local_perf_index) const
Pressure difference between segment and perforation.
Definition: MultisegmentWellSegments.cpp:248
void updateUpwindingSegments(const PrimaryVariables &primary_variables)
Update upwinding segments.
Definition: MultisegmentWellSegments.cpp:213
Definition: MultisegmentWellAssemble.hpp:35
This file contains a set of helper functions used by VFPProd / VFPInj.
Definition: blackoilbioeffectsmodules.hh:45
Class encapsulating some information about parallel wells.
Definition: MSWellHelpers.hpp:34
Definition: DeferredLogger.hpp:56
Definition: MultisegmentWellSegments.hpp:44
Definition: BlackoilWellModelGeneric.hpp:75
Definition: MultisegmentWellSegments.hpp:34