Spe5FluidSystem.hpp
Go to the documentation of this file.
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 This file is part of the Open Porous Media project (OPM).
5
6 OPM is free software: you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation, either version 2 of the License, or
9 (at your option) any later version.
10
11 OPM is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
15
16 You should have received a copy of the GNU General Public License
17 along with OPM. If not, see <http://www.gnu.org/licenses/>.
18
19 Consult the COPYING file in the top-level source directory of this
20 module for the precise wording of the license and the list of
21 copyright holders.
22*/
27#ifndef OPM_SPE5_FLUID_SYSTEM_HPP
28#define OPM_SPE5_FLUID_SYSTEM_HPP
29
30#include "BaseFluidSystem.hpp"
32
35
37
38namespace Opm {
39
54template <class Scalar>
56 : public BaseFluidSystem<Scalar, Spe5FluidSystem<Scalar> >
57{
59
60 typedef typename ::Opm::PengRobinsonMixture<Scalar, ThisType> PengRobinsonMixture;
61 typedef typename ::Opm::PengRobinson<Scalar> PengRobinson;
62
63 static const Scalar R;
64
65public:
67 template <class Evaluation>
68 struct ParameterCache : public Spe5ParameterCache<Evaluation, ThisType>
69 {};
70
71 /****************************************
72 * Fluid phase parameters
73 ****************************************/
74
76 static const int numPhases = 3;
77
79 static const int gasPhaseIdx = 0;
81 static const int waterPhaseIdx = 1;
83 static const int oilPhaseIdx = 2;
84
86 typedef ::Opm::H2O<Scalar> H2O;
87
89 static const char* phaseName(unsigned phaseIdx)
90 {
91 static const char* name[] = {
92 "gas",
93 "water",
94 "oil",
95 };
96
97 assert(phaseIdx < numPhases);
98 return name[phaseIdx];
99 }
100
102 static bool isLiquid(unsigned phaseIdx)
103 {
104 //assert(0 <= phaseIdx && phaseIdx < numPhases);
105 return phaseIdx != gasPhaseIdx;
106 }
107
113 static bool isCompressible(unsigned /*phaseIdx*/)
114 {
115 //assert(0 <= phaseIdx && phaseIdx < numPhases);
116 return true;
117 }
118
120 static bool isIdealGas(unsigned /*phaseIdx*/)
121 {
122 //assert(0 <= phaseIdx && phaseIdx < numPhases);
123 return false; // gas is not ideal here!
124 }
125
127 static bool isIdealMixture(unsigned phaseIdx)
128 {
129 // always use the reference oil for the fugacity coefficents,
130 // so they cannot be dependent on composition and they the
131 // phases thus always an ideal mixture
132 return phaseIdx == waterPhaseIdx;
133 }
134
135 /****************************************
136 * Component related parameters
137 ****************************************/
138
140 static const int numComponents = 7;
141
142 static const int H2OIdx = 0;
143 static const int C1Idx = 1;
144 static const int C3Idx = 2;
145 static const int C6Idx = 3;
146 static const int C10Idx = 4;
147 static const int C15Idx = 5;
148 static const int C20Idx = 6;
149
151 static const char* componentName(unsigned compIdx)
152 {
153 static const char* name[] = {
154 H2O::name(),
155 "C1",
156 "C3",
157 "C6",
158 "C10",
159 "C15",
160 "C20"
161 };
162
163 assert(0 <= compIdx && compIdx < numComponents);
164 return name[compIdx];
165 }
166
168 static Scalar molarMass(unsigned compIdx)
169 {
170 return
171 (compIdx == H2OIdx)
173 : (compIdx == C1Idx)
174 ? 16.04e-3
175 : (compIdx == C3Idx)
176 ? 44.10e-3
177 : (compIdx == C6Idx)
178 ? 86.18e-3
179 : (compIdx == C10Idx)
180 ? 142.29e-3
181 : (compIdx == C15Idx)
182 ? 206.00e-3
183 : (compIdx == C20Idx)
184 ? 282.00e-3
185 : 1e30;
186 }
187
191 static Scalar criticalTemperature(unsigned compIdx)
192 {
193 return
194 (compIdx == H2OIdx)
196 : (compIdx == C1Idx)
197 ? 343.0*5/9
198 : (compIdx == C3Idx)
199 ? 665.7*5/9
200 : (compIdx == C6Idx)
201 ? 913.4*5/9
202 : (compIdx == C10Idx)
203 ? 1111.8*5/9
204 : (compIdx == C15Idx)
205 ? 1270.0*5/9
206 : (compIdx == C20Idx)
207 ? 1380.0*5/9
208 : 1e30;
209 }
210
214 static Scalar criticalPressure(unsigned compIdx)
215 {
216 return
217 (compIdx == H2OIdx)
219 : (compIdx == C1Idx)
220 ? 667.8 * 6894.7573
221 : (compIdx == C3Idx)
222 ? 616.3 * 6894.7573
223 : (compIdx == C6Idx)
224 ? 436.9 * 6894.7573
225 : (compIdx == C10Idx)
226 ? 304.0 * 6894.7573
227 : (compIdx == C15Idx)
228 ? 200.0 * 6894.7573
229 : (compIdx == C20Idx)
230 ? 162.0 * 6894.7573
231 : 1e30;
232 }
233
237 static Scalar criticalMolarVolume(unsigned compIdx)
238 {
239 return
240 (compIdx == H2OIdx)
242 : (compIdx == C1Idx)
244 : (compIdx == C3Idx)
246 : (compIdx == C6Idx)
248 : (compIdx == C10Idx)
250 : (compIdx == C15Idx)
252 : (compIdx == C20Idx)
254 : 1e30;
255 }
256
260 static Scalar acentricFactor(unsigned compIdx)
261 {
262 return
263 (compIdx == H2OIdx)
265 : (compIdx == C1Idx)
266 ? 0.0130
267 : (compIdx == C3Idx)
268 ? 0.1524
269 : (compIdx == C6Idx)
270 ? 0.3007
271 : (compIdx == C10Idx)
272 ? 0.4885
273 : (compIdx == C15Idx)
274 ? 0.6500
275 : (compIdx == C20Idx)
276 ? 0.8500
277 : 1e30;
278 }
279
285 static Scalar interactionCoefficient(unsigned comp1Idx, unsigned comp2Idx)
286 {
287 unsigned i = std::min(comp1Idx, comp2Idx);
288 unsigned j = std::max(comp1Idx, comp2Idx);
289 if (i == C1Idx && (j == C15Idx || j == C20Idx))
290 return 0.05;
291 else if (i == C3Idx && (j == C15Idx || j == C20Idx))
292 return 0.005;
293 return 0;
294 }
295
296 /****************************************
297 * Methods which compute stuff
298 ****************************************/
299
308 static void init(Scalar minT = 273.15,
309 Scalar maxT = 373.15,
310 Scalar minP = 1e4,
311 Scalar maxP = 100e6)
312 {
313 PengRobinsonParamsMixture<Scalar, ThisType, gasPhaseIdx, /*useSpe5=*/true> prParams;
314
315 // find envelopes of the 'a' and 'b' parameters for the range
316 // minT <= T <= maxT and minP <= p <= maxP. For
317 // this we take advantage of the fact that 'a' and 'b' for
318 // mixtures is just a convex combination of the attractive and
319 // repulsive parameters of the pure components
320
321 Scalar minA = 1e30, maxA = -1e30;
322 Scalar minB = 1e30, maxB = -1e30;
323
324 prParams.updatePure(minT, minP);
325 for (unsigned compIdx = 0; compIdx < numComponents; ++compIdx) {
326 minA = std::min(prParams.pureParams(compIdx).a(), minA);
327 maxA = std::max(prParams.pureParams(compIdx).a(), maxA);
328 minB = std::min(prParams.pureParams(compIdx).b(), minB);
329 maxB = std::max(prParams.pureParams(compIdx).b(), maxB);
330 };
331
332 prParams.updatePure(maxT, minP);
333 for (unsigned compIdx = 0; compIdx < numComponents; ++compIdx) {
334 minA = std::min(prParams.pureParams(compIdx).a(), minA);
335 maxA = std::max(prParams.pureParams(compIdx).a(), maxA);
336 minB = std::min(prParams.pureParams(compIdx).b(), minB);
337 maxB = std::max(prParams.pureParams(compIdx).b(), maxB);
338 };
339
340 prParams.updatePure(minT, maxP);
341 for (unsigned compIdx = 0; compIdx < numComponents; ++compIdx) {
342 minA = std::min(prParams.pureParams(compIdx).a(), minA);
343 maxA = std::max(prParams.pureParams(compIdx).a(), maxA);
344 minB = std::min(prParams.pureParams(compIdx).b(), minB);
345 maxB = std::max(prParams.pureParams(compIdx).b(), maxB);
346 };
347
348 prParams.updatePure(maxT, maxP);
349 for (unsigned compIdx = 0; compIdx < numComponents; ++compIdx) {
350 minA = std::min(prParams.pureParams(compIdx).a(), minA);
351 maxA = std::max(prParams.pureParams(compIdx).a(), maxA);
352 minB = std::min(prParams.pureParams(compIdx).b(), minB);
353 maxB = std::max(prParams.pureParams(compIdx).b(), maxB);
354 };
355
356 PengRobinson::init(/*aMin=*/minA, /*aMax=*/maxA, /*na=*/100,
357 /*bMin=*/minB, /*bMax=*/maxB, /*nb=*/200);
358 }
359
361 template <class FluidState, class LhsEval = typename FluidState::Scalar, class ParamCacheEval = LhsEval>
362 static LhsEval density(const FluidState& fluidState,
363 const ParameterCache<ParamCacheEval>& paramCache,
364 unsigned phaseIdx)
365 {
366 assert(phaseIdx < numPhases);
367
368 return fluidState.averageMolarMass(phaseIdx)/paramCache.molarVolume(phaseIdx);
369 }
370
372 template <class FluidState, class LhsEval = typename FluidState::Scalar, class ParamCacheEval = LhsEval>
373 static LhsEval viscosity(const FluidState& /*fluidState*/,
374 const ParameterCache<ParamCacheEval>& /*paramCache*/,
375 unsigned phaseIdx)
376 {
377 assert(phaseIdx <= numPhases);
378
379 if (phaseIdx == gasPhaseIdx) {
380 // given by SPE-5 in table on page 64. we use a constant
381 // viscosity, though...
382 return 0.0170e-2 * 0.1;
383 }
384 else if (phaseIdx == waterPhaseIdx)
385 // given by SPE-5: 0.7 centi-Poise = 0.0007 Pa s
386 return 0.7e-2 * 0.1;
387 else {
388 assert(phaseIdx == oilPhaseIdx);
389 // given by SPE-5 in table on page 64. we use a constant
390 // viscosity, though...
391 return 0.208e-2 * 0.1;
392 }
393 }
394
396 template <class FluidState, class LhsEval = typename FluidState::Scalar, class ParamCacheEval = LhsEval>
397 static LhsEval fugacityCoefficient(const FluidState& fluidState,
398 const ParameterCache<ParamCacheEval>& paramCache,
399 unsigned phaseIdx,
400 unsigned compIdx)
401 {
402 assert(phaseIdx <= numPhases);
403 assert(compIdx <= numComponents);
404
405 if (phaseIdx == oilPhaseIdx || phaseIdx == gasPhaseIdx)
407 paramCache,
408 phaseIdx,
409 compIdx);
410 else {
411 assert(phaseIdx == waterPhaseIdx);
412 return
413 henryCoeffWater_(compIdx, fluidState.temperature(waterPhaseIdx))
414 / fluidState.pressure(waterPhaseIdx);
415 }
416 }
417
418protected:
419 template <class LhsEval>
420 static LhsEval henryCoeffWater_(unsigned compIdx, const LhsEval& temperature)
421 {
422 // use henry's law for the solutes and the vapor pressure for
423 // the solvent.
424 switch (compIdx) {
425 case H2OIdx: return H2O::vaporPressure(temperature);
426
427 // the values of the Henry constant for the solutes have
428 // are faked so far...
429 case C1Idx: return 5.57601e+09;
430 case C3Idx: return 1e10;
431 case C6Idx: return 1e10;
432 case C10Idx: return 1e10;
433 case C15Idx: return 1e10;
434 case C20Idx: return 1e10;
435 default: throw std::logic_error("Unknown component index "+std::to_string(compIdx));
436 }
437 }
438};
439
440template <class Scalar>
441const Scalar Spe5FluidSystem<Scalar>::R = Constants<Scalar>::R;
442
443} // namespace Opm
444
445#endif
The base class for all fluid systems.
Definition: BaseFluidSystem.hpp:44
Scalar Scalar
The type used for scalar quantities.
Definition: BaseFluidSystem.hpp:49
static const Scalar R
The ideal gas constant [J/(mol K)].
Definition: Constants.hpp:45
static const Scalar criticalTemperature()
Returns the critical temperature of water.
Definition: H2O.hpp:92
static Evaluation vaporPressure(Evaluation temperature)
The vapor pressure in of pure water at a given temperature.
Definition: H2O.hpp:138
static const Scalar criticalMolarVolume()
Returns the molar volume of water at the critical point.
Definition: H2O.hpp:110
static const Scalar acentricFactor()
The acentric factor of water.
Definition: H2O.hpp:86
static const Scalar criticalPressure()
Returns the critical pressure of water.
Definition: H2O.hpp:98
static const Scalar molarMass()
The molar mass in of water.
Definition: H2O.hpp:80
static const char * name()
A human readable name for the water.
Definition: H2O.hpp:74
Implements the Peng-Robinson equation of state for a mixture.
Definition: PengRobinsonMixture.hpp:41
static LhsEval computeFugacityCoefficient(const FluidState &fs, const Params &params, unsigned phaseIdx, unsigned compIdx)
Returns the fugacity coefficient of an individual component in the phase.
Definition: PengRobinsonMixture.hpp:89
The mixing rule for the oil and the gas phases of the SPE5 problem.
Definition: PengRobinsonParamsMixture.hpp:60
void updatePure(const FluidState &fluidState)
Update Peng-Robinson parameters for the pure components.
Definition: PengRobinsonParamsMixture.hpp:82
const PureParams & pureParams(unsigned compIdx) const
Return the Peng-Robinson parameters of a pure substance,.
Definition: PengRobinsonParamsMixture.hpp:205
Scalar a() const
Returns the attractive parameter 'a' of the Peng-Robinson fluid.
Definition: PengRobinsonParams.hpp:50
Scalar b() const
Returns the repulsive parameter 'b' of the Peng-Robinson fluid.
Definition: PengRobinsonParams.hpp:57
Implements the Peng-Robinson equation of state for liquids and gases.
Definition: PengRobinson.hpp:56
static void init(Scalar, Scalar, unsigned, Scalar, Scalar, unsigned)
Definition: PengRobinson.hpp:64
The fluid system for the oil, gas and water phases of the SPE5 problem.
Definition: Spe5FluidSystem.hpp:57
static const int oilPhaseIdx
Index of the oil phase.
Definition: Spe5FluidSystem.hpp:83
static LhsEval henryCoeffWater_(unsigned compIdx, const LhsEval &temperature)
Definition: Spe5FluidSystem.hpp:420
static bool isIdealMixture(unsigned phaseIdx)
Returns true if and only if a fluid phase is assumed to be an ideal mixture.
Definition: Spe5FluidSystem.hpp:127
static const int H2OIdx
Index of the water component.
Definition: Spe5FluidSystem.hpp:142
static const int numComponents
Number of chemical species in the fluid system.
Definition: Spe5FluidSystem.hpp:140
static const int C15Idx
Index of the C15 component.
Definition: Spe5FluidSystem.hpp:147
static const int numPhases
Number of fluid phases in the fluid system.
Definition: Spe5FluidSystem.hpp:76
static LhsEval fugacityCoefficient(const FluidState &fluidState, const ParameterCache< ParamCacheEval > &paramCache, unsigned phaseIdx, unsigned compIdx)
Calculate the fugacity coefficient [Pa] of an individual component in a fluid phase.
Definition: Spe5FluidSystem.hpp:397
static Scalar criticalPressure(unsigned compIdx)
Critical pressure of a component [Pa].
Definition: Spe5FluidSystem.hpp:214
static const char * phaseName(unsigned phaseIdx)
Return the human readable name of a fluid phase.
Definition: Spe5FluidSystem.hpp:89
static LhsEval density(const FluidState &fluidState, const ParameterCache< ParamCacheEval > &paramCache, unsigned phaseIdx)
Calculate the density [kg/m^3] of a fluid phase.
Definition: Spe5FluidSystem.hpp:362
static Scalar criticalTemperature(unsigned compIdx)
Critical temperature of a component [K].
Definition: Spe5FluidSystem.hpp:191
static Scalar criticalMolarVolume(unsigned compIdx)
Molar volume of a component at the critical point [m^3/mol].
Definition: Spe5FluidSystem.hpp:237
static Scalar acentricFactor(unsigned compIdx)
The acentric factor of a component [].
Definition: Spe5FluidSystem.hpp:260
static LhsEval viscosity(const FluidState &, const ParameterCache< ParamCacheEval > &, unsigned phaseIdx)
Calculate the dynamic viscosity of a fluid phase [Pa*s].
Definition: Spe5FluidSystem.hpp:373
static void init(Scalar minT=273.15, Scalar maxT=373.15, Scalar minP=1e4, Scalar maxP=100e6)
Initialize the fluid system's static parameters.
Definition: Spe5FluidSystem.hpp:308
static const int C1Idx
Index of the C1 component.
Definition: Spe5FluidSystem.hpp:143
static bool isCompressible(unsigned)
Returns true if and only if a fluid phase is assumed to be compressible.
Definition: Spe5FluidSystem.hpp:113
static const int C20Idx
Index of the C20 component.
Definition: Spe5FluidSystem.hpp:148
static const int C6Idx
Index of the C6 component.
Definition: Spe5FluidSystem.hpp:145
static const int C10Idx
Index of the C10 component.
Definition: Spe5FluidSystem.hpp:146
static Scalar interactionCoefficient(unsigned comp1Idx, unsigned comp2Idx)
Returns the interaction coefficient for two components.
Definition: Spe5FluidSystem.hpp:285
static const int waterPhaseIdx
Index of the water phase.
Definition: Spe5FluidSystem.hpp:81
static Scalar molarMass(unsigned compIdx)
Return the molar mass of a component in [kg/mol].
Definition: Spe5FluidSystem.hpp:168
::Opm::H2O< Scalar > H2O
The component for pure water to be used.
Definition: Spe5FluidSystem.hpp:86
static const int C3Idx
Index of the C3 component.
Definition: Spe5FluidSystem.hpp:144
static bool isLiquid(unsigned phaseIdx)
Return whether a phase is liquid.
Definition: Spe5FluidSystem.hpp:102
static const int gasPhaseIdx
Index of the gas phase.
Definition: Spe5FluidSystem.hpp:79
static const char * componentName(unsigned compIdx)
Return the human readable name of a component.
Definition: Spe5FluidSystem.hpp:151
static bool isIdealGas(unsigned)
Returns true if and only if a fluid phase is assumed to be an ideal gas.
Definition: Spe5FluidSystem.hpp:120
Specifies the parameter cache used by the SPE-5 fluid system.
Definition: Spe5ParameterCache.hpp:47
Scalar molarVolume(unsigned phaseIdx) const
Returns the molar volume of a phase [m^3/mol].
Definition: Spe5ParameterCache.hpp:202
Definition: Air_Mesitylene.hpp:34
ReturnEval_< Evaluation1, Evaluation2 >::type min(const Evaluation1 &arg1, const Evaluation2 &arg2)
Definition: MathToolbox.hpp:346
ReturnEval_< Evaluation1, Evaluation2 >::type max(const Evaluation1 &arg1, const Evaluation2 &arg2)
Definition: MathToolbox.hpp:341
The type of the fluid system's parameter cache.
Definition: Spe5FluidSystem.hpp:69