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