version 3.11-dev
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Pages Concepts
fluidsystems/brine.hh
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// SPDX-FileCopyrightText: Copyright © DuMux Project contributors, see AUTHORS.md in root folder
5// SPDX-License-Identifier: GPL-3.0-or-later
6//
12#ifndef DUMUX_BRINE_FLUID_SYSTEM_HH
13#define DUMUX_BRINE_FLUID_SYSTEM_HH
14
15#include <dune/common/math.hh>
16
18#include <dumux/io/name.hh>
24
25namespace Dumux::FluidSystems {
26
32template< class Scalar, class H2OType = Components::TabulatedComponent<Dumux::Components::H2O<Scalar>> >
33class Brine : public Base< Scalar, Brine<Scalar, H2OType>>
34{
36
37public:
39 using H2O = H2OType;
41
42 static const int numPhases = 1;
43 static const int numComponents = 2;
44
45 static constexpr int phase0Idx = 0;
46 static constexpr int liquidPhaseIdx = phase0Idx;
47
48 static constexpr int H2OIdx = 0;
49 static constexpr int NaClIdx = 1;
50 static constexpr int comp0Idx = H2OIdx;
51 static constexpr int comp1Idx = NaClIdx;
52
57 static const std::string phaseName(int phaseIdx = liquidPhaseIdx)
58 {
59 assert(phaseIdx == liquidPhaseIdx);
60 return IOName::liquidPhase();
61 }
62
67 static constexpr bool isMiscible()
68 {
69 return false;
70 }
71
76 static constexpr bool isGas(int phaseIdx = liquidPhaseIdx)
77 {
78 assert(phaseIdx == liquidPhaseIdx);
79 return false;
80 }
81
96 static bool isIdealMixture(int phaseIdx = liquidPhaseIdx)
97 {
98 assert(phaseIdx == liquidPhaseIdx);
99 return true;
100 }
101
111 static bool isCompressible(int phaseIdx = liquidPhaseIdx)
112 {
113 assert(phaseIdx == liquidPhaseIdx);
114 return H2O::liquidIsCompressible();
115 }
116
124 static bool isIdealGas(int phaseIdx = liquidPhaseIdx)
125 {
126 assert(phaseIdx == liquidPhaseIdx);
127 return false; /*we're a liquid!*/
128 }
129
130 /****************************************
131 * Component related static parameters
132 ****************************************/
133
138 static std::string componentName(int compIdx)
139 {
140 switch (compIdx)
141 {
142 case H2OIdx: return H2O::name();
143 case NaClIdx: return NaCl::name();
144 };
145 DUNE_THROW(Dune::InvalidStateException, "Invalid component index " << compIdx);
146 }
147
152 static Scalar molarMass(int compIdx)
153 {
154 switch (compIdx)
155 {
156 case H2OIdx: return H2O::molarMass();
157 case NaClIdx: return NaCl::molarMass();
158 };
159 DUNE_THROW(Dune::InvalidStateException, "Invalid component index " << compIdx);
160 }
161
162 /****************************************
163 * thermodynamic relations
164 ****************************************/
170 static void init()
171 {
172 init(/*tempMin=*/273.15,
173 /*tempMax=*/623.15,
174 /*numTemp=*/100,
175 /*pMin=*/-10.,
176 /*pMax=*/20e6,
177 /*numP=*/200);
178 }
179
191 static void init(Scalar tempMin, Scalar tempMax, unsigned nTemp,
192 Scalar pressMin, Scalar pressMax, unsigned nPress)
193 {
194
195 if (H2O::isTabulated)
196 {
197 std::cout << "Initializing tables for the H2O fluid properties ("
198 << nTemp*nPress
199 << " entries).\n";
200
201 H2O::init(tempMin, tempMax, nTemp, pressMin, pressMax, nPress);
202 }
203 }
204
216 template <class FluidState>
217 static Scalar density(const FluidState& fluidState, int phaseIdx = liquidPhaseIdx)
218 {
219 assert(phaseIdx == liquidPhaseIdx);
220 const Scalar temperature = fluidState.temperature(phaseIdx);
221 const Scalar pressure = fluidState.pressure(phaseIdx);
222 const Scalar xNaCl = fluidState.massFraction(phaseIdx, NaClIdx);
223
224 using std::max;
225 const Scalar TempC = temperature - 273.15;
226 const Scalar pMPa = pressure/1.0E6;
227 const Scalar salinity = max(0.0, xNaCl);
228
229 const Scalar rhow = H2O::liquidDensity(temperature, pressure);
230 const Scalar density = rhow + 1000*salinity*(0.668 +
231 0.44*salinity +
232 1.0E-6*(300*pMPa -
233 2400*pMPa*salinity +
234 TempC*(80.0 +
235 3*TempC -
236 3300*salinity -
237 13*pMPa +
238 47*pMPa*salinity)));
239 assert(density > 0.0);
240 return density;
241 }
242
245 template <class FluidState>
246 static Scalar fugacityCoefficient(const FluidState &fluidState,
247 int phaseIdx,
248 int compIdx)
249 {
250 assert(0 <= phaseIdx && phaseIdx < numPhases);
251 assert(0 <= compIdx && compIdx < numComponents);
252
253 if (phaseIdx == compIdx)
254 // We could calculate the real fugacity coefficient of
255 // the component in the fluid. Probably that's not worth
256 // the effort, since the fugacity coefficient of the other
257 // component is infinite anyway...
258 return 1.0;
259 return std::numeric_limits<Scalar>::infinity();
260 }
261
274 template <class FluidState>
275 static Scalar viscosity(const FluidState& fluidState, int phaseIdx = liquidPhaseIdx)
276 {
277 assert(phaseIdx == liquidPhaseIdx);
278 const Scalar temperature = fluidState.temperature(phaseIdx);
279 const Scalar xNaCl = fluidState.massFraction(phaseIdx, NaClIdx);
280
281 using std::pow;
282 using Dune::power;
283 using std::exp;
284 using std::max;
285 const Scalar T = max(temperature, 275.0);
286 const Scalar salinity = max(0.0, xNaCl);
287
288 const Scalar T_C = T - 273.15;
289 const Scalar A = ((0.42*power((pow(salinity, 0.8)-0.17), 2)) + 0.045)*pow(T_C, 0.8);
290 const Scalar mu_brine = 0.1 + (0.333*salinity) + (1.65+(91.9*salinity*salinity*salinity))*exp(-A); // [cP]
291 assert(mu_brine > 0.0);
292 return mu_brine/1000.0; // [Pa·s]
293 }
294
305 template <class FluidState>
306 static Scalar vaporPressure(const FluidState& fluidState, int compIdx)
307 {
308 if (compIdx == H2OIdx)
309 {
310 const Scalar temperature = fluidState.temperature(H2OIdx);
311 // Raoult's law, see Thomas Fetzer's Dissertation Eq. 2.11.
312 return H2O::vaporPressure(temperature)*fluidState.moleFraction(phase0Idx, H2OIdx);
313 }
314 else if (compIdx == NaClIdx)
315 DUNE_THROW(Dune::NotImplemented, "NaCl::vaporPressure(t)");
316 else
317 DUNE_THROW(Dune::NotImplemented, "Invalid component index " << compIdx);
318 }
319
334 template <class FluidState>
335 static Scalar enthalpy(const FluidState& fluidState, int phaseIdx)
336 {
337 //use private enthalpy function to recycle it for the heat capacity calculation
338 return enthalpy_(fluidState.pressure(phaseIdx),
339 fluidState.temperature(phaseIdx),
340 fluidState.massFraction(phase0Idx, NaClIdx)); /*J/kg*/
341 }
342
350 template <class FluidState>
351 static Scalar componentEnthalpy(const FluidState &fluidState,
352 int phaseIdx,
353 int componentIdx)
354 {
355 const Scalar T = fluidState.temperature(liquidPhaseIdx);
356 const Scalar p = fluidState.pressure(liquidPhaseIdx);
357
358 if (phaseIdx == liquidPhaseIdx)
359 {
360 if (componentIdx == H2OIdx)
361 return H2O::liquidEnthalpy(T, p);
362 else if (componentIdx == NaClIdx)
363 DUNE_THROW(Dune::NotImplemented, "The component enthalpy for NaCl is not implemented.");
364 DUNE_THROW(Dune::InvalidStateException, "Invalid component index " << componentIdx);
365 }
366 DUNE_THROW(Dune::InvalidStateException, "Invalid phase index " << phaseIdx);
367 }
368
371 template <class FluidState>
372 static Scalar molarDensity(const FluidState& fluidState, int phaseIdx = liquidPhaseIdx)
373 {
374 return density(fluidState, phaseIdx)/fluidState.averageMolarMass(phaseIdx);
375 }
376
379 template <class FluidState>
380 static Scalar diffusionCoefficient(const FluidState& fluidState, int phaseIdx, int compIdx)
381 {
382 DUNE_THROW(Dune::NotImplemented, "FluidSystems::Brine::diffusionCoefficient()");
383 }
384
400 template <class FluidState>
401 static Scalar binaryDiffusionCoefficient(const FluidState& fluidState,
402 int phaseIdx,
403 int compIIdx,
404 int compJIdx)
405 {
406 if (phaseIdx == liquidPhaseIdx)
407 {
408 if (compIIdx > compJIdx)
409 {
410 using std::swap;
411 swap(compIIdx, compJIdx);
412 }
413
414 if (compJIdx == NaClIdx)
415 return 1.54e-9;
416 else
417 DUNE_THROW(Dune::NotImplemented, "Binary diffusion coefficient of components "
418 << compIIdx << " and " << compJIdx
419 << " in phase " << phaseIdx);
420 }
421
422 DUNE_THROW(Dune::InvalidStateException, "Invalid phase index: " << phaseIdx);
423 }
424
433 template <class FluidState>
434 static Scalar thermalConductivity(const FluidState& fluidState, int phaseIdx)
435 {
436 if (phaseIdx == liquidPhaseIdx)
437 {
438 Scalar tempC = fluidState.temperature(phaseIdx)-273.15;
439 Scalar m = fluidState.moleFraction(phaseIdx, NaClIdx)/(molarMass(H2OIdx)*(1- fluidState.moleFraction(phaseIdx, NaClIdx))); // molality of NaCl
440 Scalar S = 5844.3 * m / (1000 + 58.443 *m);
441 Scalar contribNaClFactor = 1.0 - (2.3434e-3 - 7.924e-6*tempC + 3.924e-8*tempC*tempC)*S + (1.06e-5 - 2.0e-8*tempC + 1.2e-10*tempC*tempC)*S*S;
442 return contribNaClFactor * H2O::liquidThermalConductivity(fluidState.temperature(phaseIdx), fluidState.pressure(phaseIdx));
443 }
444 DUNE_THROW(Dune::InvalidStateException, "Invalid phase index: " << phaseIdx);
445 }
446
449 template <class FluidState>
450 static Scalar heatCapacity(const FluidState &fluidState, int phaseIdx)
451 {
452 if (phaseIdx == liquidPhaseIdx){
453 const Scalar eps = fluidState.temperature(phaseIdx)*1e-8;
454 //calculate heat capacity from the difference in enthalpy with temperature at constant pressure.
455 return (enthalpy_(fluidState.pressure(phaseIdx),
456 fluidState.temperature(phaseIdx) +eps ,
457 fluidState.massFraction(phase0Idx, NaClIdx))
458 - enthalpy_(fluidState.pressure(phaseIdx),
459 fluidState.temperature(phaseIdx),
460 fluidState.massFraction(phase0Idx, NaClIdx)))/eps; /*J/kg*/
461 }
462 DUNE_THROW(Dune::InvalidStateException, "Invalid phase index " << phaseIdx);
463 }
464
465private:
476 static Scalar enthalpy_(const Scalar p, const Scalar T, const Scalar xNaCl)
477 {
478 /*Numerical coefficients from PALLISER*/
479 static const Scalar f[] = { 2.63500E-1, 7.48368E-6, 1.44611E-6, -3.80860E-10 };
480
481 /*Numerical coefficients from MICHAELIDES for the enthalpy of brine*/
482 static const Scalar a[4][3] = { { +9633.6, -4080.0, +286.49 },
483 { +166.58, +68.577, -4.6856 },
484 { -0.90963, -0.36524, +0.249667E-1 },
485 { +0.17965E-2, +0.71924E-3, -0.4900E-4 } };
486
487 const Scalar theta = T - 273.15;
488 const Scalar salSat = f[0] + f[1]*theta + f[2]*theta*theta + f[3]*theta*theta*theta;
489
490 /*Regularization*/
491 using std::min;
492 using std::max;
493 const Scalar salinity = min(max(xNaCl,0.0), salSat);
494
495 const Scalar hw = H2O::liquidEnthalpy(T, p)/1E3; /* kJ/kg */
496
497 /*component enthalpy of soluted NaCl after DAUBERT and DANNER*/
498 const Scalar h_NaCl = (3.6710E4*T + 0.5*(6.2770E1)*T*T - ((6.6670E-2)/3)*T*T*T
499 + ((2.8000E-5)/4)*(T*T*T*T))/(58.44E3)- 2.045698e+02; /* U [kJ/kg] */
500
501 const Scalar m = (1E3/58.44)*(salinity/(1-salinity));
502
503 using Dune::power;
504 Scalar d_h = 0;
505 for (int i = 0; i<=3; i++)
506 for (int j=0; j<=2; j++)
507 d_h = d_h + a[i][j] * power(theta, i) * power(m, j);
508
509 /* heat of dissolution for halite according to Michaelides 1981 */
510 const Scalar delta_h = (4.184/(1E3 + (58.44 * m)))*d_h;
511
512 /* Enthalpy of brine without any dissolved gas */
513 const Scalar h_ls1 =(1-salinity)*hw + salinity*h_NaCl + salinity*delta_h; /* kJ/kg */
514 return h_ls1*1E3; /*J/kg*/
515 }
516};
517
518} // end namespace Dumux::FluidSystems
519
520#endif
A class for the NaCl properties.
Definition: nacl.hh:34
static std::string name()
A human readable name for the NaCl.
Definition: nacl.hh:39
static constexpr Scalar molarMass()
The molar mass of NaCl in .
Definition: nacl.hh:47
Fluid system base class.
Definition: fluidsystems/base.hh:32
A compositional single phase fluid system consisting of two components, which are H2O and NaCl.
Definition: fluidsystems/brine.hh:34
static Scalar thermalConductivity(const FluidState &fluidState, int phaseIdx)
Thermal conductivity of a fluid phase .
Definition: fluidsystems/brine.hh:434
static Scalar viscosity(const FluidState &fluidState, int phaseIdx=liquidPhaseIdx)
Return the viscosity of the phase.
Definition: fluidsystems/brine.hh:275
static Scalar componentEnthalpy(const FluidState &fluidState, int phaseIdx, int componentIdx)
Returns the specific enthalpy of a component in a specific phase.
Definition: fluidsystems/brine.hh:351
static bool isIdealGas(int phaseIdx=liquidPhaseIdx)
Returns true if and only if a fluid phase is assumed to be an ideal gas.
Definition: fluidsystems/brine.hh:124
static Scalar diffusionCoefficient(const FluidState &fluidState, int phaseIdx, int compIdx)
Calculate the binary molecular diffusion coefficient for a component in a fluid phase .
Definition: fluidsystems/brine.hh:380
static constexpr int phase0Idx
Index of the first (and only) phase.
Definition: fluidsystems/brine.hh:45
static constexpr bool isGas(int phaseIdx=liquidPhaseIdx)
Return whether a phase is gaseous.
Definition: fluidsystems/brine.hh:76
static constexpr int comp0Idx
index of the first component
Definition: fluidsystems/brine.hh:50
static const int numComponents
Number of components in the fluid system (H2O, NaCl)
Definition: fluidsystems/brine.hh:43
static void init(Scalar tempMin, Scalar tempMax, unsigned nTemp, Scalar pressMin, Scalar pressMax, unsigned nPress)
Initialize the fluid system's static parameters using problem specific temperature and pressure range...
Definition: fluidsystems/brine.hh:191
static Scalar fugacityCoefficient(const FluidState &fluidState, int phaseIdx, int compIdx)
Calculate the fugacity coefficient of an individual component in a fluid phase.
Definition: fluidsystems/brine.hh:246
static constexpr int comp1Idx
index of the second component
Definition: fluidsystems/brine.hh:51
static constexpr int H2OIdx
index of the water component
Definition: fluidsystems/brine.hh:48
static Scalar heatCapacity(const FluidState &fluidState, int phaseIdx)
Specific isobaric heat capacity of a fluid phase .
Definition: fluidsystems/brine.hh:450
static Scalar molarMass(int compIdx)
Return the molar mass of a component in .
Definition: fluidsystems/brine.hh:152
static Scalar enthalpy(const FluidState &fluidState, int phaseIdx)
Given a phase's composition, temperature and pressure, return its specific enthalpy .
Definition: fluidsystems/brine.hh:335
static Scalar vaporPressure(const FluidState &fluidState, int compIdx)
Vapor pressure of a component .
Definition: fluidsystems/brine.hh:306
static const std::string phaseName(int phaseIdx=liquidPhaseIdx)
Return the human readable name of the phase.
Definition: fluidsystems/brine.hh:57
static constexpr int NaClIdx
index of the NaCl component
Definition: fluidsystems/brine.hh:49
H2OType H2O
export the involved components
Definition: fluidsystems/brine.hh:39
static constexpr bool isMiscible()
Returns whether the fluids are miscible.
Definition: fluidsystems/brine.hh:67
static Scalar molarDensity(const FluidState &fluidState, int phaseIdx=liquidPhaseIdx)
Calculate the molar density of a fluid phase.
Definition: fluidsystems/brine.hh:372
static constexpr int liquidPhaseIdx
The one considered phase is liquid.
Definition: fluidsystems/brine.hh:46
static bool isCompressible(int phaseIdx=liquidPhaseIdx)
Returns true if and only if a fluid phase is assumed to be compressible.
Definition: fluidsystems/brine.hh:111
static std::string componentName(int compIdx)
Return the human readable name of a component.
Definition: fluidsystems/brine.hh:138
static Scalar density(const FluidState &fluidState, int phaseIdx=liquidPhaseIdx)
Return the phase density [kg/m^3].
Definition: fluidsystems/brine.hh:217
static bool isIdealMixture(int phaseIdx=liquidPhaseIdx)
Returns true if and only if a fluid phase is assumed to be an ideal mixture.
Definition: fluidsystems/brine.hh:96
static const int numPhases
Number of phases in the fluid system.
Definition: fluidsystems/brine.hh:42
static void init()
Initialize the fluid system's static parameters generically.
Definition: fluidsystems/brine.hh:170
static Scalar binaryDiffusionCoefficient(const FluidState &fluidState, int phaseIdx, int compIIdx, int compJIdx)
Given a phase's composition, temperature and pressure, return the binary diffusion coefficient for c...
Definition: fluidsystems/brine.hh:401
A central place for various physical constants occurring in some equations.
Some exceptions thrown in DuMux
Fluid system base class.
Material properties of pure water .
Material properties of pure salt .
A collection of input/output field names for common physical quantities.
Definition: h2o.hh:901
std::string temperature() noexcept
I/O name of temperature for equilibrium models.
Definition: name.hh:39
std::string liquidPhase() noexcept
I/O name of liquid phase.
Definition: name.hh:107
std::string pressure(int phaseIdx) noexcept
I/O name of pressure for multiphase systems.
Definition: name.hh:22
Tabulates all thermodynamic properties of a given untabulated chemical species.