My Project
Loading...
Searching...
No Matches
BrineCo2Pvt.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_BRINE_CO2_PVT_HPP
28#define OPM_BRINE_CO2_PVT_HPP
29
31#include <opm/common/TimingMacros.hpp>
32#include <opm/common/ErrorMacros.hpp>
33#include <opm/common/utility/gpuDecorators.hpp>
34
36
42#include <opm/material/components/CO2Tables.hpp>
45
46#include <opm/input/eclipse/EclipseState/Co2StoreConfig.hpp>
47
48#include <cstddef>
49#include <vector>
50
51namespace Opm {
52
53class EclipseState;
54class Schedule;
55class Co2StoreConfig;
56class EzrokhiTable;
57
58// forward declaration of the class so the function in the next namespace can be declared
59template <class Scalar, class Params, class ContainerT>
60class BrineCo2Pvt;
61
62// declaration of make_view in correct namespace so friend function can be declared in the class
63namespace gpuistl {
64 template <class ViewType, class OutputParams, class InputParams, class ContainerType, class ScalarT>
65 BrineCo2Pvt<ScalarT, OutputParams, ViewType>
66 make_view(BrineCo2Pvt<ScalarT, InputParams, ContainerType>&);
67}
68
73template <class Scalar, class Params = Opm::CO2Tables<double, std::vector<double>>, class ContainerT = std::vector<Scalar>>
75{
76 static constexpr bool extrapolate = true;
77 //typedef H2O<Scalar> H2O_IAPWS;
78 //typedef Brine<Scalar, H2O_IAPWS> Brine_IAPWS;
79 //typedef TabulatedComponent<Scalar, H2O_IAPWS> H2O_Tabulated;
80 //typedef TabulatedComponent<Scalar, Brine_IAPWS> Brine_Tabulated;
81
82 //typedef H2O_Tabulated H2O;
83 //typedef Brine_Tabulated Brine;
84
85
86public:
90
93
94 BrineCo2Pvt() = default;
95
96 explicit BrineCo2Pvt(const ContainerT& salinity,
97 int activityModel = 3,
98 int thermalMixingModelSalt = 1,
99 int thermalMixingModelLiquid = 2,
100 Scalar T_ref = 288.71, //(273.15 + 15.56)
101 Scalar P_ref = 101325);
102
103 BrineCo2Pvt(const ContainerT& brineReferenceDensity,
104 const ContainerT& co2ReferenceDensity,
105 const ContainerT& salinity,
106 int activityModel,
107 Co2StoreConfig::SaltMixingType thermalMixingModelSalt,
108 Co2StoreConfig::LiquidMixingType thermalMixingModelLiquid,
109 Params params)
110 : brineReferenceDensity_(brineReferenceDensity)
111 , co2ReferenceDensity_(co2ReferenceDensity)
112 , salinity_(salinity)
113 , activityModel_(activityModel)
114 , liquidMixType_(thermalMixingModelLiquid)
115 , saltMixType_(thermalMixingModelSalt)
116 , co2Tables_(params)
117{
118}
119
120#if HAVE_ECL_INPUT
125 void initFromState(const EclipseState& eclState, const Schedule&);
126#endif
127
128 void setNumRegions(std::size_t numRegions);
129
130 void setVapPars(const Scalar, const Scalar)
131 {
132 }
133
137 void setReferenceDensities(unsigned regionIdx,
138 Scalar rhoRefBrine,
139 Scalar rhoRefCO2,
140 Scalar /*rhoRefWater*/);
141
145 void initEnd()
146 {
147 }
148
155 void setEnableDissolvedGas(bool yesno)
156 { enableDissolution_ = yesno; }
157
165 { enableSaltConcentration_ = yesno; }
166
170 void setActivityModelSalt(int activityModel);
171
175 void setThermalMixingModel(int thermalMixingModelSalt, int thermalMixingModelLiquid);
176
177 void setEzrokhiDenCoeff(const std::vector<EzrokhiTable>& denaqa);
178
179 void setEzrokhiViscCoeff(const std::vector<EzrokhiTable>& viscaqa);
180
184 unsigned numRegions() const
185 { return brineReferenceDensity_.size(); }
186
187 OPM_HOST_DEVICE Scalar hVap(unsigned ) const{
188 return 0;
189 }
190
194 template <class Evaluation>
195 OPM_HOST_DEVICE Evaluation internalEnergy(unsigned regionIdx,
196 const Evaluation& temperature,
197 const Evaluation& pressure,
198 const Evaluation& Rs,
199 const Evaluation& saltConcentration) const
200 {
201 OPM_TIMEFUNCTION_LOCAL();
202 const Evaluation salinity = salinityFromConcentration(regionIdx, temperature, pressure, saltConcentration);
203 const Evaluation xlCO2 = convertRsToXoG_(Rs,regionIdx);
204 return (liquidEnthalpyBrineCO2_(temperature,
205 pressure,
206 salinity,
207 xlCO2)
208 - pressure / density(regionIdx, temperature, pressure, Rs, salinity ));
209 }
213 template <class Evaluation>
214 OPM_HOST_DEVICE Evaluation internalEnergy(unsigned regionIdx,
215 const Evaluation& temperature,
216 const Evaluation& pressure,
217 const Evaluation& Rs) const
218 {
219 OPM_TIMEFUNCTION_LOCAL();
220 const Evaluation xlCO2 = convertRsToXoG_(Rs,regionIdx);
221 return (liquidEnthalpyBrineCO2_(temperature,
222 pressure,
223 Evaluation(salinity_[regionIdx]),
224 xlCO2)
225 - pressure / density(regionIdx, temperature, pressure, Rs, Evaluation(salinity_[regionIdx])));
226 }
227
231 template <class Evaluation>
232 OPM_HOST_DEVICE Evaluation viscosity(unsigned regionIdx,
233 const Evaluation& temperature,
234 const Evaluation& pressure,
235 const Evaluation& /*Rs*/) const
236 {
237 //TODO: The viscosity does not yet depend on the composition
238 return saturatedViscosity(regionIdx, temperature, pressure);
239 }
240
244 template <class Evaluation>
245 OPM_HOST_DEVICE Evaluation saturatedViscosity(unsigned regionIdx,
246 const Evaluation& temperature,
247 const Evaluation& pressure,
248 const Evaluation& saltConcentration) const
249 {
250 OPM_TIMEFUNCTION_LOCAL();
251 const Evaluation salinity = salinityFromConcentration(regionIdx, temperature, pressure, saltConcentration);
252 if (enableEzrokhiViscosity_) {
253 const Evaluation& mu_pure = H2O::liquidViscosity(temperature, pressure, extrapolate);
254 const Evaluation& nacl_exponent = ezrokhiExponent_(temperature, ezrokhiViscNaClCoeff_);
255 return mu_pure * pow(10.0, nacl_exponent * salinity);
256 }
257 else {
258 return Brine::liquidViscosity(temperature, pressure, salinity);
259 }
260 }
261
265 template <class Evaluation>
266 OPM_HOST_DEVICE Evaluation viscosity(unsigned regionIdx,
267 const Evaluation& temperature,
268 const Evaluation& pressure,
269 const Evaluation& /*Rsw*/,
270 const Evaluation& saltConcentration) const
271 {
272 OPM_TIMEFUNCTION_LOCAL();
273 //TODO: The viscosity does not yet depend on the composition
274 return saturatedViscosity(regionIdx, temperature, pressure, saltConcentration);
275 }
276
280 template <class Evaluation>
281 OPM_HOST_DEVICE Evaluation saturatedViscosity(unsigned regionIdx,
282 const Evaluation& temperature,
283 const Evaluation& pressure) const
284 {
285 OPM_TIMEFUNCTION_LOCAL();
286 if (enableEzrokhiViscosity_) {
287 const Evaluation& mu_pure = H2O::liquidViscosity(temperature, pressure, extrapolate);
288 const Evaluation& nacl_exponent = ezrokhiExponent_(temperature, ezrokhiViscNaClCoeff_);
289 return mu_pure * pow(10.0, nacl_exponent * Evaluation(salinity_[regionIdx]));
290 }
291 else {
292 return Brine::liquidViscosity(temperature, pressure, Evaluation(salinity_[regionIdx]));
293 }
294
295 }
296
297
301 template <class Evaluation>
302 OPM_HOST_DEVICE Evaluation saturatedInverseFormationVolumeFactor(unsigned regionIdx,
303 const Evaluation& temperature,
304 const Evaluation& pressure,
305 const Evaluation& saltconcentration) const
306 {
307 OPM_TIMEFUNCTION_LOCAL();
308 const Evaluation salinity = salinityFromConcentration(regionIdx, temperature,
309 pressure, saltconcentration);
310 Evaluation rs_sat = rsSat(regionIdx, temperature, pressure, salinity);
311 return (1.0 - convertRsToXoG_(rs_sat,regionIdx)) * density(regionIdx, temperature,
312 pressure, rs_sat, salinity)
313 / brineReferenceDensity_[regionIdx];
314 }
318 template <class Evaluation>
319 OPM_HOST_DEVICE Evaluation inverseFormationVolumeFactor(unsigned regionIdx,
320 const Evaluation& temperature,
321 const Evaluation& pressure,
322 const Evaluation& Rs,
323 const Evaluation& saltConcentration) const
324 {
325 OPM_TIMEFUNCTION_LOCAL();
326 const Evaluation salinity = salinityFromConcentration(regionIdx, temperature,
327 pressure, saltConcentration);
328 return (1.0 - convertRsToXoG_(Rs,regionIdx)) * density(regionIdx, temperature,
329 pressure, Rs, salinity)
330 / brineReferenceDensity_[regionIdx];
331 }
335 template <class Evaluation>
336 OPM_HOST_DEVICE Evaluation inverseFormationVolumeFactor(unsigned regionIdx,
337 const Evaluation& temperature,
338 const Evaluation& pressure,
339 const Evaluation& Rs) const
340 {
341 return (1.0 - convertRsToXoG_(Rs,regionIdx)) * density(regionIdx, temperature, pressure,
342 Rs, Evaluation(salinity_[regionIdx]))
343 / brineReferenceDensity_[regionIdx];
344 }
345
349 template <class Evaluation>
350 OPM_HOST_DEVICE Evaluation saturatedInverseFormationVolumeFactor(unsigned regionIdx,
351 const Evaluation& temperature,
352 const Evaluation& pressure) const
353 {
354 OPM_TIMEFUNCTION_LOCAL();
355 Evaluation rs_sat = rsSat(regionIdx, temperature, pressure, Evaluation(salinity_[regionIdx]));
356 return (1.0 - convertRsToXoG_(rs_sat,regionIdx)) * density(regionIdx, temperature, pressure,
357 rs_sat, Evaluation(salinity_[regionIdx]))
358 / brineReferenceDensity_[regionIdx];
359 }
360
367 template <class Evaluation>
368 OPM_HOST_DEVICE Evaluation saturationPressure(unsigned /*regionIdx*/,
369 const Evaluation& /*temperature*/,
370 const Evaluation& /*Rs*/) const
371 {
372#if OPM_IS_INSIDE_DEVICE_FUNCTION
373 assert(false && "Requested the saturation pressure for the brine-co2 pvt module. Not yet implemented.");
374#else
375 throw std::runtime_error("Requested the saturation pressure for the brine-co2 pvt module. "
376 "Not yet implemented.");
377#endif
378 }
379
386 template <class Evaluation>
387 OPM_HOST_DEVICE Evaluation saturationPressure(unsigned /*regionIdx*/,
388 const Evaluation& /*temperature*/,
389 const Evaluation& /*Rs*/,
390 const Evaluation& /*saltConcentration*/) const
391 {
392#if OPM_IS_INSIDE_DEVICE_FUNCTION
393 assert(false && "Requested the saturation pressure for the brine-co2 pvt module. Not yet implemented.");
394#else
395 throw std::runtime_error("Requested the saturation pressure for the brine-co2 pvt module. "
396 "Not yet implemented.");
397#endif
398 }
399
403 template <class Evaluation>
404 OPM_HOST_DEVICE Evaluation saturatedGasDissolutionFactor(unsigned regionIdx,
405 const Evaluation& temperature,
406 const Evaluation& pressure,
407 const Evaluation& /*oilSaturation*/,
408 const Evaluation& /*maxOilSaturation*/) const
409 {
410 //TODO support VAPPARS
411 return rsSat(regionIdx, temperature, pressure, Evaluation(salinity_[regionIdx]));
412 }
413
417 template <class Evaluation>
418 OPM_HOST_DEVICE Evaluation saturatedGasDissolutionFactor(unsigned regionIdx,
419 const Evaluation& temperature,
420 const Evaluation& pressure,
421 const Evaluation& saltConcentration) const
422 {
423 const Evaluation salinity = salinityFromConcentration(regionIdx, temperature,
424 pressure, saltConcentration);
425 return rsSat(regionIdx, temperature, pressure, salinity);
426 }
427
431 template <class Evaluation>
432 OPM_HOST_DEVICE Evaluation saturatedGasDissolutionFactor(unsigned regionIdx,
433 const Evaluation& temperature,
434 const Evaluation& pressure) const
435 {
436 return rsSat(regionIdx, temperature, pressure, Evaluation(salinity_[regionIdx]));
437 }
438
439 OPM_HOST_DEVICE Scalar oilReferenceDensity(unsigned regionIdx) const
440 { return brineReferenceDensity_[regionIdx]; }
441
442 OPM_HOST_DEVICE Scalar waterReferenceDensity(unsigned regionIdx) const
443 { return brineReferenceDensity_[regionIdx]; }
444
445 OPM_HOST_DEVICE Scalar gasReferenceDensity(unsigned regionIdx) const
446 { return co2ReferenceDensity_[regionIdx]; }
447
448 OPM_HOST_DEVICE Scalar salinity(unsigned regionIdx) const
449 { return salinity_[regionIdx]; }
450
451 OPM_HOST_DEVICE const ContainerT& getBrineReferenceDensity() const
452 { return brineReferenceDensity_; }
453
454 OPM_HOST_DEVICE const ContainerT& getCo2ReferenceDensity() const
455 { return co2ReferenceDensity_; }
456
457 OPM_HOST_DEVICE const ContainerT& getSalinity() const
458 { return salinity_; }
459
460 OPM_HOST_DEVICE const Params& getParams() const
461 { return co2Tables_; }
462
463 OPM_HOST_DEVICE Co2StoreConfig::SaltMixingType getThermalMixingModelSalt() const
464 { return saltMixType_; }
465
466 OPM_HOST_DEVICE Co2StoreConfig::LiquidMixingType getThermalMixingModelLiquid() const
467 { return liquidMixType_; }
468
469 OPM_HOST_DEVICE int getActivityModel() const
470 { return activityModel_; }
471
472 template <class Evaluation>
473 OPM_HOST_DEVICE Evaluation diffusionCoefficient(const Evaluation& temperature,
474 const Evaluation& pressure,
475 unsigned /*compIdx*/) const
476 {
477 OPM_TIMEFUNCTION_LOCAL();
478 // Diffusion coefficient of CO2 in pure water according to
479 // (McLachlan and Danckwerts, 1972)
480 const Evaluation log_D_H20 = -4.1764 + 712.52 / temperature
481 -2.5907e5 / (temperature * temperature);
482
483 // Diffusion coefficient of CO2 in the brine phase modified following
484 // (Ratcliff and Holdcroft,1963 and Al-Rawajfeh, 2004)
485
486 // Water viscosity
487 const Evaluation& mu_H20 = H2O::liquidViscosity(temperature, pressure, extrapolate);
488 Evaluation mu_Brine;
489 if (enableEzrokhiViscosity_) {
490 const Evaluation& nacl_exponent = ezrokhiExponent_(temperature,
491 ezrokhiViscNaClCoeff_);
492 mu_Brine = mu_H20 * pow(10.0, nacl_exponent * Evaluation(salinity_[0]));
493 }
494 else {
495 // Brine viscosity
496 mu_Brine = Brine::liquidViscosity(temperature, pressure, Evaluation(salinity_[0]));
497 }
498 const Evaluation log_D_Brine = log_D_H20 - 0.87*log10(mu_Brine / mu_H20);
499
500 return pow(Evaluation(10), log_D_Brine) * 1e-4; // convert from cm2/s to m2/s
501 }
502
503 template <class Evaluation>
504 OPM_HOST_DEVICE Evaluation density(unsigned regionIdx,
505 const Evaluation& temperature,
506 const Evaluation& pressure,
507 const Evaluation& Rs,
508 const Evaluation& salinity) const
509 {
510 OPM_TIMEFUNCTION_LOCAL();
511 Evaluation xlCO2 = convertXoGToxoG_(convertRsToXoG_(Rs,regionIdx), salinity);
512 Evaluation result = liquidDensity_(temperature,
513 pressure,
514 xlCO2,
515 salinity);
516
517 Valgrind::CheckDefined(result);
518 return result;
519 }
520
521 template <class Evaluation>
522 OPM_HOST_DEVICE Evaluation rsSat(unsigned regionIdx,
523 const Evaluation& temperature,
524 const Evaluation& pressure,
525 const Evaluation& salinity) const
526 {
527 OPM_TIMEFUNCTION_LOCAL();
528 if (!enableDissolution_) {
529 return 0.0;
530 }
531
532 // calulate the equilibrium composition for the given
533 // temperature and pressure.
534 Evaluation xgH2O;
535 Evaluation xlCO2;
537 temperature,
538 pressure,
539 salinity,
540 /*knownPhaseIdx=*/-1,
541 xlCO2,
542 xgH2O,
543 activityModel_,
544 extrapolate);
545
546 // normalize the phase compositions
547 xlCO2 = max(0.0, min(1.0, xlCO2));
548
549 return convertXoGToRs(convertxoGToXoG(xlCO2, salinity), regionIdx);
550 }
551
552private:
553 template <class LhsEval>
554 OPM_HOST_DEVICE LhsEval ezrokhiExponent_(const LhsEval& temperature,
555 const ContainerT& ezrokhiCoeff) const
556 {
557 const LhsEval& tempC = temperature - 273.15;
558 return ezrokhiCoeff[0] + tempC * (ezrokhiCoeff[1] + ezrokhiCoeff[2] * tempC);
559 }
560
561 template <class LhsEval>
562 OPM_HOST_DEVICE LhsEval liquidDensity_(const LhsEval& T,
563 const LhsEval& pl,
564 const LhsEval& xlCO2,
565 const LhsEval& salinity) const
566 {
567 OPM_TIMEFUNCTION_LOCAL();
568 Valgrind::CheckDefined(T);
569 Valgrind::CheckDefined(pl);
570 Valgrind::CheckDefined(xlCO2);
571
572 if (!extrapolate && T < 273.15) {
573#if OPM_IS_INSIDE_DEVICE_FUNCTION
574 assert(false && "Liquid density for Brine and CO2 is only defined above 273.15K");
575#else
576 const std::string msg =
577 "Liquid density for Brine and CO2 is only "
578 "defined above 273.15K (is " +
579 std::to_string(getValue(T)) + "K)";
580 throw NumericalProblem(msg);
581#endif
582 }
583 if (!extrapolate && pl >= 2.5e8) {
584#if OPM_IS_INSIDE_DEVICE_FUNCTION
585 assert(false && "Liquid density for Brine and CO2 is only defined below 250MPa");
586#else
587 const std::string msg =
588 "Liquid density for Brine and CO2 is only "
589 "defined below 250MPa (is " +
590 std::to_string(getValue(pl)) + "Pa)";
591 throw NumericalProblem(msg);
592#endif
593 }
594
595 const LhsEval& rho_pure = H2O::liquidDensity(T, pl, extrapolate);
596 if (enableEzrokhiDensity_) {
597 const LhsEval& nacl_exponent = ezrokhiExponent_(T, ezrokhiDenNaClCoeff_);
598 const LhsEval& co2_exponent = ezrokhiExponent_(T, ezrokhiDenCo2Coeff_);
599 const LhsEval& XCO2 = convertxoGToXoG(xlCO2, salinity);
600 return rho_pure * pow(10.0, nacl_exponent * salinity + co2_exponent * XCO2);
601 }
602 else {
603 const LhsEval& rho_brine = Brine::liquidDensity(T, pl, salinity, extrapolate);
604 const LhsEval& rho_lCO2 = liquidDensityWaterCO2_(T, pl, xlCO2);
605 const LhsEval& contribCO2 = rho_lCO2 - rho_pure;
606 return rho_brine + contribCO2;
607 }
608 }
609
610 template <class LhsEval>
611 OPM_HOST_DEVICE LhsEval liquidDensityWaterCO2_(const LhsEval& temperature,
612 const LhsEval& pl,
613 const LhsEval& xlCO2) const
614 {
615 OPM_TIMEFUNCTION_LOCAL();
616 Scalar M_CO2 = CO2::molarMass();
617 Scalar M_H2O = H2O::molarMass();
618
619 const LhsEval& tempC = temperature - 273.15; /* tempC : temperature in °C */
620 const LhsEval& rho_pure = H2O::liquidDensity(temperature, pl, extrapolate);
621 // calculate the mole fraction of CO2 in the liquid. note that xlH2O is available
622 // as a function parameter, but in the case of a pure gas phase the value of M_T
623 // for the virtual liquid phase can become very large
624 const LhsEval xlH2O = 1.0 - xlCO2;
625 const LhsEval& M_T = M_H2O * xlH2O + M_CO2 * xlCO2;
626 const LhsEval& V_phi =
627 (37.51 +
628 tempC*(-9.585e-2 +
629 tempC*(8.74e-4 -
630 tempC*5.044e-7))) / 1.0e6;
631 return 1 / (xlCO2 * V_phi/M_T + M_H2O * xlH2O / (rho_pure * M_T));
632 }
633
638 template <class LhsEval>
639 OPM_HOST_DEVICE LhsEval convertRsToXoG_(const LhsEval& Rs, unsigned regionIdx) const
640 {
641 OPM_TIMEFUNCTION_LOCAL();
642 Scalar rho_oRef = brineReferenceDensity_[regionIdx];
643 Scalar rho_gRef = co2ReferenceDensity_[regionIdx];
644
645 const LhsEval& rho_oG = Rs*rho_gRef;
646 return rho_oG/(rho_oRef + rho_oG);
647 }
648
652 template <class LhsEval>
653 OPM_HOST_DEVICE LhsEval convertXoGToxoG_(const LhsEval& XoG, const LhsEval& salinity) const
654 {
655 OPM_TIMEFUNCTION_LOCAL();
656 Scalar M_CO2 = CO2::molarMass();
657 LhsEval M_Brine = Brine::molarMass(salinity);
658 return XoG*M_Brine / (M_CO2*(1 - XoG) + XoG*M_Brine);
659 }
660
664 template <class LhsEval>
665 OPM_HOST_DEVICE LhsEval convertxoGToXoG(const LhsEval& xoG, const LhsEval& salinity) const
666 {
667 OPM_TIMEBLOCK_LOCAL(convertxoGToXoG);
668 Scalar M_CO2 = CO2::molarMass();
669 LhsEval M_Brine = Brine::molarMass(salinity);
670
671 return xoG*M_CO2 / (xoG*(M_CO2 - M_Brine) + M_Brine);
672 }
673
678 template <class LhsEval>
679 OPM_HOST_DEVICE LhsEval convertXoGToRs(const LhsEval& XoG, unsigned regionIdx) const
680 {
681 Scalar rho_oRef = brineReferenceDensity_[regionIdx];
682 Scalar rho_gRef = co2ReferenceDensity_[regionIdx];
683
684 return XoG/(1.0 - XoG)*(rho_oRef/rho_gRef);
685 }
686
687 template <class LhsEval>
688 OPM_HOST_DEVICE LhsEval liquidEnthalpyBrineCO2_(const LhsEval& T,
689 const LhsEval& p,
690 const LhsEval& salinity,
691 const LhsEval& X_CO2_w) const
692 {
693 if (liquidMixType_ == Co2StoreConfig::LiquidMixingType::NONE
694 && saltMixType_ == Co2StoreConfig::SaltMixingType::NONE)
695 {
696 return H2O::liquidEnthalpy(T, p);
697 }
698
699 LhsEval hw = H2O::liquidEnthalpy(T, p) /1E3; /* kJ/kg */
700 LhsEval h_ls1 = hw;
701 // Use mixing model for salt by MICHAELIDES
702 if (saltMixType_ == Co2StoreConfig::SaltMixingType::MICHAELIDES) {
703
704 /* X_CO2_w : mass fraction of CO2 in brine */
705
706 /* same function as enthalpy_brine, only extended by CO2 content */
707
708 /*Numerical coefficents from PALLISER*/
709 static constexpr Scalar f[] = {
710 2.63500E-1, 7.48368E-6, 1.44611E-6, -3.80860E-10
711 };
712
713 /*Numerical coefficents from MICHAELIDES for the enthalpy of brine*/
714 static constexpr Scalar a[4][3] = {
715 { 9633.6, -4080.0, +286.49 },
716 { +166.58, +68.577, -4.6856 },
717 { -0.90963, -0.36524, +0.249667E-1 },
718 { +0.17965E-2, +0.71924E-3, -0.4900E-4 }
719 };
720
721 LhsEval theta, h_NaCl;
722 LhsEval d_h, delta_h;
723
724 theta = T - 273.15;
725
726 // Regularization
727 Scalar scalarTheta = scalarValue(theta);
728 Scalar S_lSAT = f[0] + scalarTheta*(f[1] + scalarTheta*(f[2] + scalarTheta*f[3]));
729
730 LhsEval S = salinity;
731 if (S > S_lSAT)
732 S = S_lSAT;
733
734 /*DAUBERT and DANNER*/
735 /*U=*/h_NaCl = (3.6710E4*T + 0.5*(6.2770E1)*T*T - ((6.6670E-2)/3)*T*T*T
736 +((2.8000E-5)/4)*(T*T*T*T))/(58.44E3)- 2.045698e+02; /* kJ/kg */
737
738 LhsEval m = 1E3 / 58.44 * S / (1 - S);
739 d_h = 0;
740
741 for (int i = 0; i <=3; ++i) {
742 for (int j = 0; j <= 2; ++j) {
743 d_h += a[i][j] * pow(theta, static_cast<Scalar>(i)) * pow(m, j);
744 }
745 }
746 /* heat of dissolution for halite according to Michaelides 1971 */
747 delta_h = (4.184/(1E3 + (58.44 * m)))*d_h;
748
749 /* Enthalpy of brine without CO2 */
750 h_ls1 =(1-S)*hw + S*h_NaCl + S*delta_h; /* kJ/kg */
751
752 // Use Enthalpy of brine without CO2
753 if (liquidMixType_ == Co2StoreConfig::LiquidMixingType::NONE) {
754 return h_ls1*1E3;
755 }
756 }
757
758 LhsEval delta_hCO2, hg;
759 /* heat of dissolution for CO2 according to Fig. 6 in Duan and Sun 2003. (kJ/kg)
760 In the relevant temperature ranges CO2 dissolution is
761 exothermal */
762 if (liquidMixType_ == Co2StoreConfig::LiquidMixingType::DUANSUN) {
763 delta_hCO2 = (-57.4375 + T * 0.1325) * 1000/44;
764 }
765 else {
766 delta_hCO2 = 0.0;
767 }
768
769 /* enthalpy contribution of CO2 (kJ/kg) */
770 hg = CO2::gasEnthalpy(co2Tables_, T, p, extrapolate)/1E3 + delta_hCO2;
771
772 /* Enthalpy of brine with dissolved CO2 */
773 return (h_ls1 - X_CO2_w*hw + hg*X_CO2_w)*1E3; /*J/kg*/
774 }
775
776 template <class LhsEval>
777 OPM_HOST_DEVICE const LhsEval salinityFromConcentration(unsigned regionIdx,
778 const LhsEval&T,
779 const LhsEval& P,
780 const LhsEval& saltConcentration) const
781 {
782 if (enableSaltConcentration_) {
783 return saltConcentration/H2O::liquidDensity(T, P, true);
784 }
785
786 return salinity(regionIdx);
787 }
788
789 template <class ViewType, class OutputParams, class InputParams, class ContainerType, class ScalarT>
790 friend BrineCo2Pvt<ScalarT, OutputParams, ViewType>
791 gpuistl::make_view(BrineCo2Pvt<ScalarT, InputParams, ContainerType>&);
792
793 ContainerT brineReferenceDensity_{};
794 ContainerT co2ReferenceDensity_{};
795 ContainerT salinity_{};
796 ContainerT ezrokhiDenNaClCoeff_{};
797 ContainerT ezrokhiDenCo2Coeff_{};
798 ContainerT ezrokhiViscNaClCoeff_{};
799 bool enableEzrokhiDensity_ = false;
800 bool enableEzrokhiViscosity_ = false;
801 bool enableDissolution_ = true;
802 bool enableSaltConcentration_ = false;
803 int activityModel_{};
804 Co2StoreConfig::LiquidMixingType liquidMixType_{};
805 Co2StoreConfig::SaltMixingType saltMixType_{};
806 Params co2Tables_;
807};
808
809} // namespace Opm
810
811namespace Opm::gpuistl
812{
813
814 template<class Params, class GPUContainer, class ScalarT>
815 BrineCo2Pvt<ScalarT, Params, GPUContainer>
816 copy_to_gpu(const BrineCo2Pvt<ScalarT>& cpuBrineCo2)
817 {
818 return BrineCo2Pvt<ScalarT, Params, GPUContainer>(
819 GPUContainer(cpuBrineCo2.getBrineReferenceDensity()),
820 GPUContainer(cpuBrineCo2.getCo2ReferenceDensity()),
821 GPUContainer(cpuBrineCo2.getSalinity()),
822 cpuBrineCo2.getActivityModel(),
823 cpuBrineCo2.getThermalMixingModelSalt(),
824 cpuBrineCo2.getThermalMixingModelLiquid(),
825 copy_to_gpu<GPUContainer>(cpuBrineCo2.getParams())
826 );
827 }
828
829 template <class ViewType, class OutputParams, class InputParams, class ContainerType, class ScalarT>
830 BrineCo2Pvt<ScalarT, OutputParams, ViewType>
831 make_view(BrineCo2Pvt<ScalarT, InputParams, ContainerType>& brineCo2Pvt)
832 {
833
834 using ContainedType = typename ViewType::value_type;
835
836 ViewType newBrineReferenceDensity = make_view<ContainedType>(brineCo2Pvt.brineReferenceDensity_);
837 ViewType newGasReferenceDensity = make_view<ContainedType>(brineCo2Pvt.co2ReferenceDensity_);
838 ViewType newSalinity = make_view<ContainedType>(brineCo2Pvt.salinity_);
839
840 return BrineCo2Pvt<ScalarT, OutputParams, ViewType>(
841 newBrineReferenceDensity,
842 newGasReferenceDensity,
843 newSalinity,
844 brineCo2Pvt.getActivityModel(),
845 brineCo2Pvt.getThermalMixingModelSalt(),
846 brineCo2Pvt.getThermalMixingModelLiquid(),
847 make_view<ViewType>(brineCo2Pvt.co2Tables_)
848 );
849 }
850}
851
852#endif
A class for the brine fluid properties.
Binary coefficients for brine and CO2.
A class for the CO2 fluid properties.
Provides the OPM specific exception classes.
Binary coefficients for water and CO2.
A simple version of pure water with density from Hu et al.
A generic class which tabulates all thermodynamic properties of a given component.
Implements a scalar function that depends on two variables and which is sampled on an uniform X-Y gri...
Binary coefficients for brine and CO2.
Definition Brine_CO2.hpp:46
static OPM_HOST_DEVICE void calculateMoleFractions(const CO2Params &params, const Evaluation &temperature, const Evaluation &pg, const Evaluation &salinity, const int knownPhaseIdx, Evaluation &xlCO2, Evaluation &ygH2O, const int &activityModel, bool extrapolate=false)
Returns the mol (!) fraction of CO2 in the liquid phase and the mol_ (!) fraction of H2O in the gas p...
Definition Brine_CO2.hpp:101
This class represents the Pressure-Volume-Temperature relations of the liquid phase for a CO2-Brine s...
Definition BrineCo2Pvt.hpp:75
OPM_HOST_DEVICE Evaluation saturatedGasDissolutionFactor(unsigned regionIdx, const Evaluation &temperature, const Evaluation &pressure) const
Returns thegas dissoluiton factor [m^3/m^3] of the liquid phase.
Definition BrineCo2Pvt.hpp:432
void setThermalMixingModel(int thermalMixingModelSalt, int thermalMixingModelLiquid)
Set thermal mixing model for co2 in brine.
Definition BrineCo2Pvt.cpp:185
OPM_HOST_DEVICE Evaluation saturatedInverseFormationVolumeFactor(unsigned regionIdx, const Evaluation &temperature, const Evaluation &pressure) const
Returns the formation volume factor [-] of brine saturated with CO2 at a given pressure.
Definition BrineCo2Pvt.hpp:350
OPM_HOST_DEVICE Evaluation internalEnergy(unsigned regionIdx, const Evaluation &temperature, const Evaluation &pressure, const Evaluation &Rs, const Evaluation &saltConcentration) const
Returns the specific enthalpy [J/kg] of gas given a set of parameters.
Definition BrineCo2Pvt.hpp:195
void initEnd()
Finish initializing the oil phase PVT properties.
Definition BrineCo2Pvt.hpp:145
OPM_HOST_DEVICE Evaluation saturatedGasDissolutionFactor(unsigned regionIdx, const Evaluation &temperature, const Evaluation &pressure, const Evaluation &, const Evaluation &) const
Returns the gas dissoluiton factor [m^3/m^3] of the liquid phase.
Definition BrineCo2Pvt.hpp:404
void setEnableDissolvedGas(bool yesno)
Specify whether the PVT model should consider that the CO2 component can dissolve in the brine phase.
Definition BrineCo2Pvt.hpp:155
unsigned numRegions() const
Return the number of PVT regions which are considered by this PVT-object.
Definition BrineCo2Pvt.hpp:184
void setEnableSaltConcentration(bool yesno)
Specify whether the PVT model should consider salt concentration from the fluidstate or a fixed salin...
Definition BrineCo2Pvt.hpp:164
void setReferenceDensities(unsigned regionIdx, Scalar rhoRefBrine, Scalar rhoRefCO2, Scalar)
Initialize the reference densities of all fluids for a given PVT region.
Definition BrineCo2Pvt.cpp:162
void setActivityModelSalt(int activityModel)
Set activity coefficient model for salt in solubility model.
Definition BrineCo2Pvt.cpp:173
OPM_HOST_DEVICE Evaluation viscosity(unsigned regionIdx, const Evaluation &temperature, const Evaluation &pressure, const Evaluation &, const Evaluation &saltConcentration) const
Returns the dynamic viscosity [Pa s] of the fluid phase given a set of parameters.
Definition BrineCo2Pvt.hpp:266
OPM_HOST_DEVICE Evaluation inverseFormationVolumeFactor(unsigned regionIdx, const Evaluation &temperature, const Evaluation &pressure, const Evaluation &Rs, const Evaluation &saltConcentration) const
Returns the formation volume factor [-] of the fluid phase.
Definition BrineCo2Pvt.hpp:319
OPM_HOST_DEVICE Evaluation saturationPressure(unsigned, const Evaluation &, const Evaluation &, const Evaluation &) const
Returns the saturation pressure of the brine phase [Pa] depending on its mass fraction of the gas com...
Definition BrineCo2Pvt.hpp:387
OPM_HOST_DEVICE Evaluation saturatedViscosity(unsigned regionIdx, const Evaluation &temperature, const Evaluation &pressure) const
Returns the dynamic viscosity [Pa s] of oil saturated gas at given pressure.
Definition BrineCo2Pvt.hpp:281
OPM_HOST_DEVICE Evaluation saturatedInverseFormationVolumeFactor(unsigned regionIdx, const Evaluation &temperature, const Evaluation &pressure, const Evaluation &saltconcentration) const
Returns the formation volume factor [-] of the fluid phase.
Definition BrineCo2Pvt.hpp:302
OPM_HOST_DEVICE Evaluation saturatedViscosity(unsigned regionIdx, const Evaluation &temperature, const Evaluation &pressure, const Evaluation &saltConcentration) const
Returns the dynamic viscosity [Pa s] of the fluid phase given a set of parameters.
Definition BrineCo2Pvt.hpp:245
OPM_HOST_DEVICE Evaluation internalEnergy(unsigned regionIdx, const Evaluation &temperature, const Evaluation &pressure, const Evaluation &Rs) const
Returns the specific enthalpy [J/kg] of gas given a set of parameters.
Definition BrineCo2Pvt.hpp:214
OPM_HOST_DEVICE Evaluation saturationPressure(unsigned, const Evaluation &, const Evaluation &) const
Returns the saturation pressure of the brine phase [Pa] depending on its mass fraction of the gas com...
Definition BrineCo2Pvt.hpp:368
OPM_HOST_DEVICE Evaluation inverseFormationVolumeFactor(unsigned regionIdx, const Evaluation &temperature, const Evaluation &pressure, const Evaluation &Rs) const
Returns the formation volume factor [-] of the fluid phase.
Definition BrineCo2Pvt.hpp:336
OPM_HOST_DEVICE Evaluation viscosity(unsigned regionIdx, const Evaluation &temperature, const Evaluation &pressure, const Evaluation &) const
Returns the dynamic viscosity [Pa s] of the fluid phase given a set of parameters.
Definition BrineCo2Pvt.hpp:232
OPM_HOST_DEVICE Evaluation saturatedGasDissolutionFactor(unsigned regionIdx, const Evaluation &temperature, const Evaluation &pressure, const Evaluation &saltConcentration) const
Returns the gas dissoluiton factor [m^3/m^3] of the liquid phase.
Definition BrineCo2Pvt.hpp:418
A class for the brine fluid properties.
Definition BrineDynamic.hpp:49
static OPM_HOST_DEVICE Evaluation liquidViscosity(const Evaluation &temperature, const Evaluation &, const Evaluation &salinity)
The dynamic viscosity of pure water.
Definition BrineDynamic.hpp:341
static OPM_HOST_DEVICE Evaluation liquidDensity(const Evaluation &temperature, const Evaluation &pressure, const Evaluation &salinity, bool extrapolate=false)
The density of the liquid component at a given pressure in and temperature in .
Definition BrineDynamic.hpp:264
A class for the CO2 fluid properties.
Definition CO2.hpp:58
static OPM_HOST_DEVICE Scalar molarMass()
The mass in [kg] of one mole of CO2.
Definition CO2.hpp:73
static OPM_HOST_DEVICE Evaluation gasEnthalpy(const Params &params, const Evaluation &temperature, const Evaluation &pressure, bool extrapolate=false)
Specific enthalpy of gaseous CO2 [J/kg].
Definition CO2.hpp:171
static Scalar molarMass()
The molar mass in of the component.
Definition Component.hpp:93
Definition EclipseState.hpp:63
Definition Schedule.hpp:101
A simple version of pure water with density from Hu et al.
Definition SimpleHuDuanH2O.hpp:65
static OPM_HOST_DEVICE Evaluation liquidDensity(const Evaluation &temperature, const Evaluation &pressure, bool extrapolate)
The density of pure water at a given pressure and temperature .
Definition SimpleHuDuanH2O.hpp:313
static OPM_HOST_DEVICE Evaluation liquidViscosity(const Evaluation &temperature, const Evaluation &pressure, bool extrapolate)
The dynamic viscosity of pure water.
Definition SimpleHuDuanH2O.hpp:358
static OPM_HOST_DEVICE Scalar molarMass()
The molar mass in of water.
Definition SimpleHuDuanH2O.hpp:102
static OPM_HOST_DEVICE Evaluation liquidEnthalpy(const Evaluation &temperature, const Evaluation &)
Specific enthalpy of liquid water .
Definition SimpleHuDuanH2O.hpp:201
This class implements a small container which holds the transmissibility mulitpliers for all the face...
Definition Exceptions.hpp:30