GCC Code Coverage Report


Directory: ../../../builds/dumux-repositories/
File: /builds/dumux-repositories/dumux/dumux/material/fluidsystems/spe5parametercache.hh
Date: 2024-09-21 20:52:54
Exec Total Coverage
Lines: 70 88 79.5%
Functions: 14 16 87.5%
Branches: 43 142 30.3%

Line Branch Exec Source
1 // -*- mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
2 // vi: set et ts=4 sw=4 sts=4:
3 //
4 // SPDX-FileCopyrightInfo: Copyright © DuMux Project contributors, see AUTHORS.md in root folder
5 // SPDX-License-Identifier: GPL-3.0-or-later
6 //
7 /*!
8 * \file
9 * \ingroup FluidSystems
10 * \brief @copybrief Dumux::Spe5ParameterCache
11 */
12 #ifndef SPE5_PARAMETER_CACHE_HH
13 #define SPE5_PARAMETER_CACHE_HH
14
15 #include <cassert>
16
17 #include <dumux/material/components/h2o.hh>
18 #include <dumux/material/fluidsystems/parametercachebase.hh>
19
20 #include <dumux/material/eos/pengrobinson.hh>
21 #include <dumux/material/eos/pengrobinsonparamsmixture.hh>
22
23 namespace Dumux {
24
25 /*!
26 * \ingroup FluidSystems
27 * \brief Specifies the parameters required by the SPE5 problem which
28 * are despondent on the thermodynamic state.
29 */
30 template <class Scalar, class FluidSystem>
31 class Spe5ParameterCache
32 : public ParameterCacheBase<Spe5ParameterCache<Scalar, FluidSystem> >
33 {
34 using ThisType = Spe5ParameterCache<Scalar, FluidSystem>;
35 using ParentType = ParameterCacheBase<ThisType>;
36
37 using PengRobinson = Dumux::PengRobinson<Scalar>;
38
39 enum { numPhases = FluidSystem::numPhases };
40
41 enum { wPhaseIdx = FluidSystem::wPhaseIdx };
42 enum { oPhaseIdx = FluidSystem::oPhaseIdx };
43 enum { gPhaseIdx = FluidSystem::gPhaseIdx };
44
45 public:
46 // types of the parameter objects for each phase
47 using OilPhaseParams = PengRobinsonParamsMixture<Scalar, FluidSystem, oPhaseIdx, /*useSpe5=*/true>;
48 using GasPhaseParams = PengRobinsonParamsMixture<Scalar, FluidSystem, gPhaseIdx, /*useSpe5=*/true>;
49
50 /*!
51 * \brief The constructor
52 */
53 53 Spe5ParameterCache()
54 {
55
4/4
✓ Branch 0 taken 156 times.
✓ Branch 1 taken 52 times.
✓ Branch 2 taken 3 times.
✓ Branch 3 taken 1 times.
212 for (int phaseIdx = 0; phaseIdx < numPhases; ++phaseIdx)
56 159 VmUpToDate_[phaseIdx] = false;
57 }
58
59 /*!
60 * \brief Update all parameters required by the fluid system to
61 * calculate some quantities for the phase.
62 * \param fs An arbitrary fluid state
63 * \param phaseIdx The index of the fluid phase to consider
64 * \param except The except quantity
65 */
66 template <class FluidState>
67 22111 void updatePhase(const FluidState &fs,
68 int phaseIdx,
69 int except = ParentType::None)
70 {
71 22111 updateEosParams(fs, phaseIdx, except);
72
73 // if we don't need to recalculate the molar volume, we exit
74 // here
75
2/2
✓ Branch 0 taken 22108 times.
✓ Branch 1 taken 3 times.
22111 if (VmUpToDate_[phaseIdx])
76 return;
77
78 // update the phase's molar volume
79 22108 updateMolarVolume_(fs, phaseIdx);
80 }
81
82 /*!
83 * \brief Update all cached parameters of a specific fluid phase
84 * which depend on the mole fraction of a single component
85 *
86 * \b Only use this method if just a single component's
87 * concentration changed between two \p update() calls. If more than
88 * one concentration changed, call updatePhaseComposition() of
89 * updatePhase()!
90
91 * \param fs An arbitrary fluid state
92 * \param compIdx The index of the component to consider
93 * \param phaseIdx The index of the fluid phase to consider
94 */
95 template <class FluidState>
96 void updateSingleMoleFraction(const FluidState &fs,
97 int phaseIdx,
98 int compIdx)
99 {
100 if (phaseIdx == oPhaseIdx)
101 oilPhaseParams_.updateSingleMoleFraction(fs, compIdx);
102 else if (phaseIdx == gPhaseIdx)
103 gasPhaseParams_.updateSingleMoleFraction(fs, compIdx);
104
105 // update the phase's molar volume
106 updateMolarVolume_(fs, phaseIdx);
107 }
108
109 /*!
110 * \brief The Peng-Robinson attractive parameter for a phase.
111 * \param phaseIdx The index of the fluid phase to consider
112 */
113 619919 Scalar a(int phaseIdx) const
114 {
115
2/3
✓ Branch 0 taken 297845 times.
✓ Branch 1 taken 322074 times.
✗ Branch 2 not taken.
619919 switch (phaseIdx)
116 {
117 297845 case oPhaseIdx: return oilPhaseParams_.a();
118 322074 case gPhaseIdx: return gasPhaseParams_.a();
119 default:
120 DUNE_THROW(Dune::InvalidStateException,
121 "The a() parameter is only defined for "
122 "oil and gas phases");
123 }
124 }
125
126 /*!
127 * \brief The Peng-Robinson co-volume for a phase.
128 * \param phaseIdx The index of the fluid phase to consider
129 */
130 619919 Scalar b(int phaseIdx) const
131 {
132
2/3
✓ Branch 0 taken 297845 times.
✓ Branch 1 taken 322074 times.
✗ Branch 2 not taken.
619919 switch (phaseIdx)
133 {
134 297845 case oPhaseIdx: return oilPhaseParams_.b();
135 322074 case gPhaseIdx: return gasPhaseParams_.b();
136 default:
137 DUNE_THROW(Dune::InvalidStateException,
138 "The b() parameter is only defined for "
139 "oil and gas phases");
140 }
141 }
142
143 /*!
144 * \brief The Peng-Robinson attractive parameter for a pure
145 * component given the same temperature and pressure of the
146 * phase.
147 * \param compIdx The index of the component to consider
148 * \param phaseIdx The index of the fluid phase to consider
149 */
150 2121728 Scalar aPure(int phaseIdx, int compIdx) const
151 {
152
2/3
✓ Branch 0 taken 1060864 times.
✓ Branch 1 taken 1060864 times.
✗ Branch 2 not taken.
2121728 switch (phaseIdx)
153 {
154 2121728 case oPhaseIdx: return oilPhaseParams_.pureParams(compIdx).a();
155 2121728 case gPhaseIdx: return gasPhaseParams_.pureParams(compIdx).a();
156 default:
157 DUNE_THROW(Dune::InvalidStateException,
158 "The a() parameter is only defined for "
159 "oil and gas phases");
160 }
161 }
162
163 /*!
164 * \brief The Peng-Robinson co-volume for a pure component given
165 * the same temperature and pressure of the phase.
166 * \param compIdx The index of the component to consider
167 * \param phaseIdx The index of the fluid phase to consider
168 */
169 265216 Scalar bPure(int phaseIdx, int compIdx) const
170 {
171
2/3
✓ Branch 0 taken 132608 times.
✓ Branch 1 taken 132608 times.
✗ Branch 2 not taken.
265216 switch (phaseIdx)
172 {
173 265216 case oPhaseIdx: return oilPhaseParams_.pureParams(compIdx).b();
174 265216 case gPhaseIdx: return gasPhaseParams_.pureParams(compIdx).b();
175 default:
176 DUNE_THROW(Dune::InvalidStateException,
177 "The b() parameter is only defined for "
178 "oil and gas phases");
179 }
180 }
181
182 /*!
183 * \brief Returns the molar volume of a phase \f$\mathrm{[m^3/mol]}\f$
184 * \param phaseIdx The index of the fluid phase to consider
185 */
186 Scalar molarVolume(int phaseIdx) const
187 {
188
7/16
✗ Branch 0 not taken.
✓ Branch 1 taken 5000 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 9972 times.
✗ Branch 6 not taken.
✓ Branch 7 taken 34905 times.
✗ Branch 9 not taken.
✓ Branch 10 taken 265205 times.
✗ Branch 12 not taken.
✓ Branch 13 taken 6966 times.
✗ Branch 15 not taken.
✗ Branch 16 not taken.
✗ Branch 18 not taken.
✓ Branch 19 taken 56827 times.
✗ Branch 21 not taken.
✓ Branch 22 taken 1 times.
378876 assert(VmUpToDate_[phaseIdx]);
189
2/2
✓ Branch 0 taken 23268 times.
✓ Branch 1 taken 11634 times.
322046 return Vm_[phaseIdx];
190 }
191
192
193 /*!
194 * \brief Returns the Peng-Robinson mixture parameters for the oil
195 * phase.
196 */
197 const OilPhaseParams &oilPhaseParams() const
198 { return oilPhaseParams_; }
199
200 /*!
201 * \brief Returns the Peng-Robinson mixture parameters for the gas
202 * phase.
203 */
204 const GasPhaseParams &gasPhaseParams() const
205 { return gasPhaseParams_; }
206
207 /*!
208 * \brief Update all parameters required by the equation of state to
209 * calculate some quantities for the phase.
210 */
211 template <class FluidState>
212 22111 void updateEosParams(const FluidState &fs,
213 int phaseIdx,
214 int exceptQuantities = ParentType::None)
215 {
216
2/2
✓ Branch 0 taken 22105 times.
✓ Branch 1 taken 6 times.
22111 if (!(exceptQuantities & ParentType::Temperature))
217 {
218 22105 updatePure_(fs, phaseIdx);
219 22105 updateMix_(fs, phaseIdx);
220 22105 VmUpToDate_[phaseIdx] = false;
221 }
222
2/2
✓ Branch 0 taken 3 times.
✓ Branch 1 taken 3 times.
6 else if (!(exceptQuantities & ParentType::Composition))
223 {
224 3 updateMix_(fs, phaseIdx);
225 3 VmUpToDate_[phaseIdx] = false;
226 }
227
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 3 times.
3 else if (!(exceptQuantities & ParentType::Pressure)) {
228 VmUpToDate_[phaseIdx] = false;
229 }
230 22111 }
231
232 protected:
233 /*!
234 * \brief Update all parameters of a phase which only depend on
235 * temperature and/or pressure.
236 *
237 * This usually means the parameters for the pure components.
238 */
239 template <class FluidState>
240 22105 void updatePure_(const FluidState &fs, int phaseIdx)
241 {
242
3/3
✓ Branch 0 taken 7361 times.
✓ Branch 1 taken 7360 times.
✓ Branch 2 taken 7360 times.
22105 Scalar T = fs.temperature(phaseIdx);
243
3/3
✓ Branch 0 taken 7361 times.
✓ Branch 1 taken 7360 times.
✓ Branch 2 taken 7360 times.
22105 Scalar p = fs.pressure(phaseIdx);
244
245
3/3
✓ Branch 0 taken 7369 times.
✓ Branch 1 taken 7368 times.
✓ Branch 2 taken 7368 times.
22105 switch (phaseIdx)
246 {
247 7369 case oPhaseIdx: oilPhaseParams_.updatePure(T, p); break;
248 7368 case gPhaseIdx: gasPhaseParams_.updatePure(T, p); break;
249 }
250 22105 }
251
252 /*!
253 * \brief Update all parameters of a phase which depend on the
254 * fluid composition. It is assumed that updatePure() has
255 * been called before this method.
256 *
257 * Here, the mixing rule kicks in.
258 */
259 template <class FluidState>
260 22108 void updateMix_(const FluidState &fs, int phaseIdx)
261 {
262
3/3
✓ Branch 0 taken 7370 times.
✓ Branch 1 taken 7369 times.
✓ Branch 2 taken 7369 times.
22108 switch (phaseIdx)
263 {
264 7370 case oPhaseIdx:
265 7370 oilPhaseParams_.updateMix(fs);
266 7370 break;
267 7369 case gPhaseIdx:
268 7369 gasPhaseParams_.updateMix(fs);
269 7369 break;
270 case wPhaseIdx:
271 break;
272 }
273 22108 }
274
275 template <class FluidState>
276 57013 void updateMolarVolume_(const FluidState &fs,
277 int phaseIdx)
278 {
279 57013 VmUpToDate_[phaseIdx] = true;
280
281 // calculate molar volume of the phase (we will need this for the
282 // fugacity coefficients and the density anyway)
283
3/4
✓ Branch 0 taken 19004 times.
✓ Branch 1 taken 19005 times.
✓ Branch 2 taken 19004 times.
✗ Branch 3 not taken.
57013 switch (phaseIdx) {
284 19004 case gPhaseIdx: {
285 // calculate molar volumes for the given composition. although
286 // this isn't a Peng-Robinson parameter strictly speaking, the
287 // molar volume appears in basically every quantity the fluid
288 // system can get queried, so it is okay to calculate it
289 // here...
290 19004 Vm_[gPhaseIdx] =
291 19004 PengRobinson::computeMolarVolume(fs,
292 *this,
293 phaseIdx,
294 /*isGasPhase=*/true);
295 19004 break;
296 }
297 19005 case oPhaseIdx: {
298 // calculate molar volumes for the given composition. although
299 // this isn't a Peng-Robinson parameter strictly speaking, the
300 // molar volume appears in basically every quantity the fluid
301 // system can get queried, so it is okay to calculate it
302 // here...
303 19005 Vm_[oPhaseIdx] =
304 19005 PengRobinson::computeMolarVolume(fs,
305 *this,
306 phaseIdx,
307 /*isGasPhase=*/false);
308 19005 break;
309 }
310 19004 case wPhaseIdx: {
311 // Density of water in the stock tank (i.e. atmospheric
312 // pressure) is specified as 62.4 lb/ft^3 by the SPE-5
313 // paper. Also 1 lb = 0.4535923 and 1 ft = 0.3048 m.
314 19004 const Scalar stockTankWaterDensity = 62.4 * 0.45359237 / 0.028316847;
315 // Water compressibility is specified as 3.3e-6 per psi
316 // overpressure, where 1 psi = 6894.7573 Pa
317 19004 Scalar overPressure = fs.pressure(wPhaseIdx) - 1.013e5; // [Pa]
318 19004 Scalar waterDensity =
319 19004 stockTankWaterDensity * (1 + 3.3e-6*overPressure/6894.7573);
320
321 // convert water density [kg/m^3] to molar volume [m^3/mol]
322 19004 Vm_[wPhaseIdx] = fs.averageMolarMass(wPhaseIdx)/waterDensity;
323 19004 break;
324 }
325 default:
326 DUNE_THROW(Dune::InvalidStateException, "invalid phaseIdx " << phaseIdx);
327 }
328 57013 }
329
330 bool VmUpToDate_[numPhases];
331 Scalar Vm_[numPhases];
332
333 OilPhaseParams oilPhaseParams_;
334 GasPhaseParams gasPhaseParams_;
335 };
336
337 } // end namespace Dumux
338
339 #endif
340