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
26
27#include <cstddef>
28#include <vector>
29
30namespace Opm {
31
32 class AutoICD;
33 struct PhaseUsage;
34 template<class Scalar> class SegmentState;
35 class UnitSystem;
36 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
50public:
51 MultisegmentWellSegments(const int numSegments,
53
54 void computeFluidProperties(const EvalWell& temperature,
55 const EvalWell& saltConcentration,
56 const PrimaryVariables& primary_variables,
57 int pvt_region_index,
58 DeferredLogger& deferred_logger);
59
61 void updateUpwindingSegments(const PrimaryVariables& primary_variables);
62
63 EvalWell getHydroPressureLoss(const int seg,
64 const int seg_side) const;
65
67 Scalar getPressureDiffSegPerf(const int seg,
68 const int perf) const;
69
70 EvalWell getSurfaceVolume(const EvalWell& temperature,
71 const EvalWell& saltConcentration,
72 const PrimaryVariables& primary_variables,
73 const int pvt_region_index,
74 const int seg_idx) const;
75
76 EvalWell getFrictionPressureLoss(const int seg,
77 const bool extra_reverse_flow_derivatives = false) const;
78
79 // pressure drop for Spiral ICD segment (WSEGSICD)
80 EvalWell pressureDropSpiralICD(const int seg,
81 const bool extra_reverse_flow_derivatives = false) const;
82
83 // pressure drop for Autonomous ICD segment (WSEGAICD)
84 EvalWell pressureDropAutoICD(const int seg,
85 const UnitSystem& unit_system,
86 const bool extra_reverse_flow_derivatives = false) const;
87
88 // pressure drop for sub-critical valve (WSEGVALV)
89 EvalWell pressureDropValve(const int seg,
90 const SummaryState& st,
91 const bool extra_reverse_flow_derivatives = false) const;
92
93 // pressure loss contribution due to acceleration
95 const double area,
96 const bool extra_reverse_flow_derivatives = false) const;
97
98 const std::vector<std::vector<int>>& inlets() const
99 {
100 return inlets_;
101 }
102
103 const std::vector<int>& inlets(const int seg) const
104 {
105 return inlets_[seg];
106 }
107
108 const std::vector<std::vector<int>>& perforations() const
109 {
110 return perforations_;
111 }
112
113 int upwinding_segment(const int seg) const
114 {
115 return upwinding_segments_[seg];
116 }
117
118 Scalar getRefDensity() const
119 {
120 return densities_[0].value();
121 }
122
123 const EvalWell& density(const int seg) const
124 {
125 return densities_[seg];
126 }
127
128 Scalar perforation_depth_diff(const int perf) const
129 {
130 return perforation_depth_diffs_[perf];
131 }
132
134 SegmentState<Scalar>& segSol) const;
135
136private:
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 std::vector<Scalar> perforation_depth_diffs_;
152
153 // the inlet segments for each segment. It is for convenience and efficiency reason
154 std::vector<std::vector<int>> inlets_;
155
156 std::vector<Scalar> depth_diffs_;
157
158 // the densities of segment fluids
159 // we should not have this member variable
160 std::vector<EvalWell> densities_;
161
162 // the mass rate of the segments
163 std::vector<EvalWell> mass_rates_;
164
165 // the viscosity of the segments
166 std::vector<EvalWell> viscosities_;
167
168 // the upwinding segment for each segment based on the flow direction
169 std::vector<int> upwinding_segments_;
170
171 std::vector<std::vector<EvalWell>> phase_densities_;
172 std::vector<std::vector<EvalWell>> phase_fractions_;
173 std::vector<std::vector<EvalWell>> phase_viscosities_;
174
176
177 void copyPhaseDensities(const unsigned phaseIdx,
178 const std::size_t stride,
179 double* dens) const;
180
181 double mixtureDensity(const int seg) const;
182 double mixtureDensityWithExponents(const int seg) const;
183 double mixtureDensityWithExponents(const AutoICD& aicd, const int seg) const;
184};
185
186} // namespace Opm
187
188#endif // OPM_MULTISEGMENTWELL_SEGMENTS_HEADER_INCLUDED
Definition: DeferredLogger.hpp:57
Definition: MultisegmentWellPrimaryVariables.hpp:45
DenseAd::Evaluation< double, Indices::numEq+numWellEq > EvalWell
Definition: MultisegmentWellPrimaryVariables.hpp:79
Definition: MultisegmentWellSegments.hpp:45
EvalWell pressureDropAutoICD(const int seg, const UnitSystem &unit_system, const bool extra_reverse_flow_derivatives=false) const
EvalWell pressureDropValve(const int seg, const SummaryState &st, const bool extra_reverse_flow_derivatives=false) const
EvalWell accelerationPressureLossContribution(const int seg, const double area, const bool extra_reverse_flow_derivatives=false) const
Scalar getPressureDiffSegPerf(const int seg, const int perf) const
Pressure difference between segment and perforation.
Scalar perforation_depth_diff(const int perf) const
Definition: MultisegmentWellSegments.hpp:128
const std::vector< std::vector< int > > & inlets() const
Definition: MultisegmentWellSegments.hpp:98
EvalWell getHydroPressureLoss(const int seg, const int seg_side) const
const EvalWell & density(const int seg) const
Definition: MultisegmentWellSegments.hpp:123
MultisegmentWellSegments(const int numSegments, WellInterfaceGeneric &well)
Scalar getRefDensity() const
Definition: MultisegmentWellSegments.hpp:118
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:108
int upwinding_segment(const int seg) const
Definition: MultisegmentWellSegments.hpp:113
void copyPhaseDensities(const PhaseUsage &pu, SegmentState< Scalar > &segSol) const
void computeFluidProperties(const EvalWell &temperature, const EvalWell &saltConcentration, const PrimaryVariables &primary_variables, int pvt_region_index, DeferredLogger &deferred_logger)
EvalWell getSurfaceVolume(const EvalWell &temperature, const EvalWell &saltConcentration, const PrimaryVariables &primary_variables, const int pvt_region_index, const int seg_idx) const
const std::vector< int > & inlets(const int seg) const
Definition: MultisegmentWellSegments.hpp:103
EvalWell pressureDropSpiralICD(const int seg, const bool extra_reverse_flow_derivatives=false) const
Definition: SegmentState.hpp:34
Definition: WellInterfaceGeneric.hpp:50
Definition: BlackoilPhases.hpp:27
Definition: BlackoilPhases.hpp:46