opm-common
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>
35#include <opm/common/utility/VectorWithDefaultAllocator.hpp>
36
38
44#include <opm/material/components/CO2Tables.hpp>
48
49#include <opm/input/eclipse/EclipseState/Co2StoreConfig.hpp>
50
51#include <cstddef>
52#include <vector>
53
54namespace Opm {
55
56class EclipseState;
57class Schedule;
58class Co2StoreConfig;
59class EzrokhiTable;
60
61// forward declaration of the class so the function in the next namespace can be declared
62template <class Scalar, template <class> class Storage>
63class BrineCo2Pvt;
64
65#if HAVE_CUDA
66// declaration of make_view in correct namespace so friend function can be declared in the class
67namespace gpuistl {
68 template <class ScalarT>
69 BrineCo2Pvt<ScalarT, GpuView>
70 make_view(BrineCo2Pvt<ScalarT, GpuBuffer>&);
71}
72#endif
73
78template <class Scalar, template <class> class Storage = Opm::VectorWithDefaultAllocator>
79class BrineCo2Pvt
80{
82 using ContainerT = Storage<Scalar>;
83 static constexpr bool extrapolate = true;
84 //typedef H2O<Scalar> H2O_IAPWS;
85 //typedef Brine<Scalar, H2O_IAPWS> Brine_IAPWS;
86 //typedef TabulatedComponent<Scalar, H2O_IAPWS> H2O_Tabulated;
87 //typedef TabulatedComponent<Scalar, Brine_IAPWS> Brine_Tabulated;
88
89 //typedef H2O_Tabulated H2O;
90 //typedef Brine_Tabulated Brine;
91
92
93public:
94 using H2O = SimpleHuDuanH2O<Scalar>;
97
100
101 BrineCo2Pvt() = default;
102
103 explicit BrineCo2Pvt(const ContainerT& salinity,
104 int activityModel = 3,
105 int thermalMixingModelSalt = 1,
106 int thermalMixingModelLiquid = 2,
107 Scalar T_ref = 288.71, //(273.15 + 15.56)
108 Scalar P_ref = 101325);
109
110 BrineCo2Pvt(const ContainerT& brineReferenceDensity,
111 const ContainerT& co2ReferenceDensity,
112 const ContainerT& salinity,
113 int activityModel,
114 Co2StoreConfig::SaltMixingType thermalMixingModelSalt,
115 Co2StoreConfig::LiquidMixingType thermalMixingModelLiquid,
116 Params params)
117 : brineReferenceDensity_(brineReferenceDensity)
118 , co2ReferenceDensity_(co2ReferenceDensity)
119 , salinity_(salinity)
120 , activityModel_(activityModel)
121 , liquidMixType_(thermalMixingModelLiquid)
122 , saltMixType_(thermalMixingModelSalt)
123 , co2Tables_(params)
124{
125}
126
127#if HAVE_ECL_INPUT
132 void initFromState(const EclipseState& eclState, const Schedule&);
133#endif
134
135 void setNumRegions(std::size_t numRegions);
136
137 void setVapPars(const Scalar, const Scalar)
138 {
139 }
140
141
142 OPM_HOST_DEVICE static constexpr bool isActive()
143 {
144 return true;
145 }
146
150 void setReferenceDensities(unsigned regionIdx,
151 Scalar rhoRefBrine,
152 Scalar rhoRefCO2,
153 Scalar /*rhoRefWater*/);
154
158 void initEnd()
159 {
160 }
161
168 void setEnableDissolvedGas(bool yesno)
169 { enableDissolution_ = yesno; }
170
178 { enableSaltConcentration_ = yesno; }
179
183 void setActivityModelSalt(int activityModel);
184
188 void setThermalMixingModel(int thermalMixingModelSalt, int thermalMixingModelLiquid);
189
190 void setEzrokhiDenCoeff(const std::vector<EzrokhiTable>& denaqa);
191
192 void setEzrokhiViscCoeff(const std::vector<EzrokhiTable>& viscaqa);
193
197 unsigned numRegions() const
198 { return brineReferenceDensity_.size(); }
199
200 OPM_HOST_DEVICE Scalar hVap(unsigned ) const{
201 return 0;
202 }
203
207 template <class Evaluation>
208 OPM_HOST_DEVICE Evaluation internalEnergy(unsigned regionIdx,
209 const Evaluation& temperature,
210 const Evaluation& pressure,
211 const Evaluation& Rs,
212 const Evaluation& saltConcentration) const
213 {
214 OPM_TIMEFUNCTION_LOCAL(Subsystem::PvtProps);
215 const Evaluation salinity = salinityFromConcentration(regionIdx, temperature, pressure, saltConcentration);
216 const Evaluation xlCO2 = convertRsToXoG_(Rs,regionIdx);
217 return (liquidEnthalpyBrineCO2_(temperature,
218 pressure,
219 salinity,
220 xlCO2)
221 - pressure / density(regionIdx, temperature, pressure, Rs, salinity ));
222 }
223
226 template <class Evaluation>
227 OPM_HOST_DEVICE Evaluation internalEnergy(unsigned regionIdx,
228 const Evaluation& temperature,
229 const Evaluation& pressure,
230 const Evaluation& Rs) const
231 {
232 OPM_TIMEFUNCTION_LOCAL(Subsystem::PvtProps);
233 const Evaluation xlCO2 = convertRsToXoG_(Rs,regionIdx);
234 return (liquidEnthalpyBrineCO2_(temperature,
235 pressure,
236 Evaluation(salinity_[regionIdx]),
237 xlCO2)
238 - pressure / density(regionIdx, temperature, pressure, Rs, Evaluation(salinity_[regionIdx])));
239 }
240
244 template <class Evaluation>
245 OPM_HOST_DEVICE Evaluation viscosity(unsigned regionIdx,
246 const Evaluation& temperature,
247 const Evaluation& pressure,
248 const Evaluation& /*Rs*/) const
249 {
250 //TODO: The viscosity does not yet depend on the composition
251 return saturatedViscosity(regionIdx, temperature, pressure);
252 }
253
257 template <class Evaluation>
258 OPM_HOST_DEVICE Evaluation saturatedViscosity(unsigned regionIdx,
259 const Evaluation& temperature,
260 const Evaluation& pressure,
261 const Evaluation& saltConcentration) const
262 {
263 OPM_TIMEFUNCTION_LOCAL(Subsystem::PvtProps);
264 const Evaluation salinity = salinityFromConcentration(regionIdx, temperature, pressure, saltConcentration);
265 if (enableEzrokhiViscosity_) {
266 const Evaluation& mu_pure = H2O::liquidViscosity(temperature, pressure, extrapolate);
267 const Evaluation& nacl_exponent = ezrokhiExponent_(temperature, ezrokhiViscNaClCoeff_);
268 return mu_pure * pow(10.0, nacl_exponent * salinity);
269 }
270 else {
271 return Brine::liquidViscosity(temperature, pressure, salinity);
272 }
273 }
274
278 template <class Evaluation>
279 OPM_HOST_DEVICE Evaluation viscosity(unsigned regionIdx,
280 const Evaluation& temperature,
281 const Evaluation& pressure,
282 const Evaluation& /*Rsw*/,
283 const Evaluation& saltConcentration) const
284 {
285 OPM_TIMEFUNCTION_LOCAL(Subsystem::PvtProps);
286 //TODO: The viscosity does not yet depend on the composition
287 return saturatedViscosity(regionIdx, temperature, pressure, saltConcentration);
288 }
289
293 template <class Evaluation>
294 OPM_HOST_DEVICE Evaluation saturatedViscosity(unsigned regionIdx,
295 const Evaluation& temperature,
296 const Evaluation& pressure) const
297 {
298 OPM_TIMEFUNCTION_LOCAL(Subsystem::PvtProps);
299 if (enableEzrokhiViscosity_) {
300 const Evaluation& mu_pure = H2O::liquidViscosity(temperature, pressure, extrapolate);
301 const Evaluation& nacl_exponent = ezrokhiExponent_(temperature, ezrokhiViscNaClCoeff_);
302 return mu_pure * pow(10.0, nacl_exponent * Evaluation(salinity_[regionIdx]));
303 }
304 else {
305 return Brine::liquidViscosity(temperature, pressure, Evaluation(salinity_[regionIdx]));
306 }
307
308 }
309
310
314 template <class Evaluation>
315 OPM_HOST_DEVICE Evaluation saturatedInverseFormationVolumeFactor(unsigned regionIdx,
316 const Evaluation& temperature,
317 const Evaluation& pressure,
318 const Evaluation& saltconcentration) const
319 {
320 OPM_TIMEFUNCTION_LOCAL(Subsystem::PvtProps);
321 const Evaluation salinity = salinityFromConcentration(regionIdx, temperature,
322 pressure, saltconcentration);
323 Evaluation rs_sat = rsSat(regionIdx, temperature, pressure, salinity);
324 return (1.0 - convertRsToXoG_(rs_sat,regionIdx)) * density(regionIdx, temperature,
325 pressure, rs_sat, salinity)
326 / brineReferenceDensity_[regionIdx];
327 }
328
331 template <class Evaluation>
332 OPM_HOST_DEVICE Evaluation inverseFormationVolumeFactor(unsigned regionIdx,
333 const Evaluation& temperature,
334 const Evaluation& pressure,
335 const Evaluation& Rs,
336 const Evaluation& saltConcentration) const
337 {
338 OPM_TIMEFUNCTION_LOCAL(Subsystem::PvtProps);
339 const Evaluation salinity = salinityFromConcentration(regionIdx, temperature,
340 pressure, saltConcentration);
341 return (1.0 - convertRsToXoG_(Rs,regionIdx)) * density(regionIdx, temperature,
342 pressure, Rs, salinity)
343 / brineReferenceDensity_[regionIdx];
344 }
345
348 template <class Evaluation>
349 OPM_HOST_DEVICE Evaluation inverseFormationVolumeFactor(unsigned regionIdx,
350 const Evaluation& temperature,
351 const Evaluation& pressure,
352 const Evaluation& Rs) const
353 {
354 return (1.0 - convertRsToXoG_(Rs,regionIdx)) * density(regionIdx, temperature, pressure,
355 Rs, Evaluation(salinity_[regionIdx]))
356 / brineReferenceDensity_[regionIdx];
357 }
358
362 template <class FluidState, class LhsEval = typename FluidState::Scalar>
363 std::pair<LhsEval, LhsEval>
364 inverseFormationVolumeFactorAndViscosity(const FluidState& fluidState, unsigned regionIdx)
365 {
366 // Deal with the possibility that we are in a two-phase CO2STORE with OIL and GAS as phases.
367 const bool waterIsActive = fluidState.phaseIsActive(FluidState::waterPhaseIdx);
368 const int myPhaseIdx = waterIsActive ? FluidState::waterPhaseIdx : FluidState::oilPhaseIdx;
369 const LhsEval& Rsw = waterIsActive ? decay<LhsEval>(fluidState.Rsw()) : decay<LhsEval>(fluidState.Rs());
370
371 const LhsEval& T = decay<LhsEval>(fluidState.temperature(myPhaseIdx));
372 const LhsEval& p = decay<LhsEval>(fluidState.pressure(myPhaseIdx));
373 const LhsEval& saltConcentration
374 = BlackOil::template getSaltConcentration_<FluidState, LhsEval>(fluidState, regionIdx);
375 // TODO: The viscosity does not yet depend on the composition
376 return { this->inverseFormationVolumeFactor(regionIdx, T, p, Rsw, saltConcentration) ,
377 this->saturatedViscosity(regionIdx, T, p, saltConcentration) };
378 }
379
383 template <class Evaluation>
384 OPM_HOST_DEVICE Evaluation saturatedInverseFormationVolumeFactor(unsigned regionIdx,
385 const Evaluation& temperature,
386 const Evaluation& pressure) const
387 {
388 OPM_TIMEFUNCTION_LOCAL(Subsystem::PvtProps);
389 Evaluation rs_sat = rsSat(regionIdx, temperature, pressure, Evaluation(salinity_[regionIdx]));
390 return (1.0 - convertRsToXoG_(rs_sat,regionIdx)) * density(regionIdx, temperature, pressure,
391 rs_sat, Evaluation(salinity_[regionIdx]))
392 / brineReferenceDensity_[regionIdx];
393 }
394
401 template <class Evaluation>
402 OPM_HOST_DEVICE Evaluation saturationPressure(unsigned /*regionIdx*/,
403 const Evaluation& /*temperature*/,
404 const Evaluation& /*Rs*/) const
405 {
406#if OPM_IS_INSIDE_DEVICE_FUNCTION
407 assert(false && "Requested the saturation pressure for the brine-co2 pvt module. Not yet implemented.");
408#else
409 throw std::runtime_error("Requested the saturation pressure for the brine-co2 pvt module. "
410 "Not yet implemented.");
411#endif
412 }
413
420 template <class Evaluation>
421 OPM_HOST_DEVICE Evaluation saturationPressure(unsigned /*regionIdx*/,
422 const Evaluation& /*temperature*/,
423 const Evaluation& /*Rs*/,
424 const Evaluation& /*saltConcentration*/) const
425 {
426#if OPM_IS_INSIDE_DEVICE_FUNCTION
427 assert(false && "Requested the saturation pressure for the brine-co2 pvt module. Not yet implemented.");
428#else
429 throw std::runtime_error("Requested the saturation pressure for the brine-co2 pvt module. "
430 "Not yet implemented.");
431#endif
432 }
433
437 template <class Evaluation>
438 OPM_HOST_DEVICE Evaluation saturatedGasDissolutionFactor(unsigned regionIdx,
439 const Evaluation& temperature,
440 const Evaluation& pressure,
441 const Evaluation& /*oilSaturation*/,
442 const Evaluation& /*maxOilSaturation*/) const
443 {
444 //TODO support VAPPARS
445 return rsSat(regionIdx, temperature, pressure, Evaluation(salinity_[regionIdx]));
446 }
447
451 template <class Evaluation>
452 OPM_HOST_DEVICE Evaluation saturatedGasDissolutionFactor(unsigned regionIdx,
453 const Evaluation& temperature,
454 const Evaluation& pressure,
455 const Evaluation& saltConcentration) const
456 {
457 const Evaluation salinity = salinityFromConcentration(regionIdx, temperature,
458 pressure, saltConcentration);
459 return rsSat(regionIdx, temperature, pressure, salinity);
460 }
461
465 template <class Evaluation>
466 OPM_HOST_DEVICE Evaluation saturatedGasDissolutionFactor(unsigned regionIdx,
467 const Evaluation& temperature,
468 const Evaluation& pressure) const
469 {
470 return rsSat(regionIdx, temperature, pressure, Evaluation(salinity_[regionIdx]));
471 }
472
473 OPM_HOST_DEVICE Scalar oilReferenceDensity(unsigned regionIdx) const
474 { return brineReferenceDensity_[regionIdx]; }
475
476 OPM_HOST_DEVICE Scalar waterReferenceDensity(unsigned regionIdx) const
477 { return brineReferenceDensity_[regionIdx]; }
478
479 OPM_HOST_DEVICE Scalar gasReferenceDensity(unsigned regionIdx) const
480 { return co2ReferenceDensity_[regionIdx]; }
481
482 OPM_HOST_DEVICE Scalar salinity(unsigned regionIdx) const
483 { return salinity_[regionIdx]; }
484
485 OPM_HOST_DEVICE const ContainerT& getBrineReferenceDensity() const
486 { return brineReferenceDensity_; }
487
488 OPM_HOST_DEVICE const ContainerT& getCo2ReferenceDensity() const
489 { return co2ReferenceDensity_; }
490
491 OPM_HOST_DEVICE const ContainerT& getSalinity() const
492 { return salinity_; }
493
494 OPM_HOST_DEVICE const Params& getParams() const
495 { return co2Tables_; }
496
497 OPM_HOST_DEVICE Co2StoreConfig::SaltMixingType getThermalMixingModelSalt() const
498 { return saltMixType_; }
499
500 OPM_HOST_DEVICE Co2StoreConfig::LiquidMixingType getThermalMixingModelLiquid() const
501 { return liquidMixType_; }
502
503 OPM_HOST_DEVICE int getActivityModel() const
504 { return activityModel_; }
505
506 template <class Evaluation>
507 OPM_HOST_DEVICE Evaluation diffusionCoefficient(const Evaluation& temperature,
508 const Evaluation& pressure,
509 unsigned /*compIdx*/) const
510 {
511 OPM_TIMEFUNCTION_LOCAL(Subsystem::PvtProps);
512 // Diffusion coefficient of CO2 in pure water according to
513 // (McLachlan and Danckwerts, 1972)
514 const Evaluation log_D_H20 = -4.1764 + 712.52 / temperature
515 -2.5907e5 / (temperature * temperature);
516
517 // Diffusion coefficient of CO2 in the brine phase modified following
518 // (Ratcliff and Holdcroft,1963 and Al-Rawajfeh, 2004)
519
520 // Water viscosity
521 const Evaluation& mu_H20 = H2O::liquidViscosity(temperature, pressure, extrapolate);
522 Evaluation mu_Brine;
523 if (enableEzrokhiViscosity_) {
524 const Evaluation& nacl_exponent = ezrokhiExponent_(temperature,
525 ezrokhiViscNaClCoeff_);
526 mu_Brine = mu_H20 * pow(10.0, nacl_exponent * Evaluation(salinity_[0]));
527 }
528 else {
529 // Brine viscosity
530 mu_Brine = Brine::liquidViscosity(temperature, pressure, Evaluation(salinity_[0]));
531 }
532 const Evaluation log_D_Brine = log_D_H20 - 0.87*log10(mu_Brine / mu_H20);
533
534 return pow(Evaluation(10), log_D_Brine) * 1e-4; // convert from cm2/s to m2/s
535 }
536
537 template <class Evaluation>
538 OPM_HOST_DEVICE Evaluation density(unsigned regionIdx,
539 const Evaluation& temperature,
540 const Evaluation& pressure,
541 const Evaluation& Rs,
542 const Evaluation& salinity) const
543 {
544 OPM_TIMEFUNCTION_LOCAL(Subsystem::PvtProps);
545 Evaluation xlCO2 = convertXoGToxoG_(convertRsToXoG_(Rs,regionIdx), salinity);
546 Evaluation result = liquidDensity_(temperature,
547 pressure,
548 xlCO2,
549 salinity);
550
551 Valgrind::CheckDefined(result);
552 return result;
553 }
554
555 template <class Evaluation>
556 OPM_HOST_DEVICE Evaluation rsSat(unsigned regionIdx,
557 const Evaluation& temperature,
558 const Evaluation& pressure,
559 const Evaluation& salinity) const
560 {
561 OPM_TIMEFUNCTION_LOCAL(Subsystem::PvtProps);
562 if (!enableDissolution_) {
563 return 0.0;
564 }
565
566 // calulate the equilibrium composition for the given
567 // temperature and pressure.
568 Evaluation xgH2O;
569 Evaluation xlCO2;
571 temperature,
572 pressure,
573 salinity,
574 /*knownPhaseIdx=*/-1,
575 xlCO2,
576 xgH2O,
577 activityModel_,
578 extrapolate);
579
580 // normalize the phase compositions
581 xlCO2 = max(0.0, min(1.0, xlCO2));
582
583 return convertXoGToRs(convertxoGToXoG(xlCO2, salinity), regionIdx);
584 }
585
586private:
587 template <class LhsEval>
588 OPM_HOST_DEVICE LhsEval ezrokhiExponent_(const LhsEval& temperature,
589 const ContainerT& ezrokhiCoeff) const
590 {
591 const LhsEval& tempC = temperature - 273.15;
592 return ezrokhiCoeff[0] + tempC * (ezrokhiCoeff[1] + ezrokhiCoeff[2] * tempC);
593 }
594
595 template <class LhsEval>
596 OPM_HOST_DEVICE LhsEval liquidDensity_(const LhsEval& T,
597 const LhsEval& pl,
598 const LhsEval& xlCO2,
599 const LhsEval& salinity) const
600 {
601 OPM_TIMEFUNCTION_LOCAL(Subsystem::PvtProps);
602 Valgrind::CheckDefined(T);
603 Valgrind::CheckDefined(pl);
604 Valgrind::CheckDefined(xlCO2);
605
606 if (!extrapolate && T < 273.15) {
607#if OPM_IS_INSIDE_DEVICE_FUNCTION
608 assert(false && "Liquid density for Brine and CO2 is only defined above 273.15K");
609#else
610 const std::string msg =
611 "Liquid density for Brine and CO2 is only "
612 "defined above 273.15K (is " +
613 std::to_string(getValue(T)) + "K)";
614 throw NumericalProblem(msg);
615#endif
616 }
617 if (!extrapolate && pl >= 2.5e8) {
618#if OPM_IS_INSIDE_DEVICE_FUNCTION
619 assert(false && "Liquid density for Brine and CO2 is only defined below 250MPa");
620#else
621 const std::string msg =
622 "Liquid density for Brine and CO2 is only "
623 "defined below 250MPa (is " +
624 std::to_string(getValue(pl)) + "Pa)";
625 throw NumericalProblem(msg);
626#endif
627 }
628
629 const LhsEval& rho_pure = H2O::liquidDensity(T, pl, extrapolate);
630 if (enableEzrokhiDensity_) {
631 const LhsEval& nacl_exponent = ezrokhiExponent_(T, ezrokhiDenNaClCoeff_);
632 const LhsEval& co2_exponent = ezrokhiExponent_(T, ezrokhiDenCo2Coeff_);
633 const LhsEval& XCO2 = convertxoGToXoG(xlCO2, salinity);
634 return rho_pure * pow(10.0, nacl_exponent * salinity + co2_exponent * XCO2);
635 }
636 else {
637 const LhsEval& rho_brine = Brine::liquidDensity(T, pl, salinity, rho_pure);
638 const LhsEval& rho_lCO2 = liquidDensityWaterCO2_(T, xlCO2, rho_pure);
639 const LhsEval& contribCO2 = rho_lCO2 - rho_pure;
640 return rho_brine + contribCO2;
641 }
642 }
643
644 template <class LhsEval>
645 OPM_HOST_DEVICE LhsEval liquidDensityWaterCO2_(const LhsEval& temperature,
646 const LhsEval& xlCO2,
647 const LhsEval& rho_pure) const
648 {
649 OPM_TIMEFUNCTION_LOCAL(Subsystem::PvtProps);
650 Scalar M_CO2 = CO2::molarMass();
651 Scalar M_H2O = H2O::molarMass();
652
653 const LhsEval& tempC = temperature - 273.15; /* tempC : temperature in °C */
654 // calculate the mole fraction of CO2 in the liquid. note that xlH2O is available
655 // as a function parameter, but in the case of a pure gas phase the value of M_T
656 // for the virtual liquid phase can become very large
657 const LhsEval xlH2O = 1.0 - xlCO2;
658 const LhsEval& M_T = M_H2O * xlH2O + M_CO2 * xlCO2;
659 const LhsEval& V_phi =
660 (37.51 +
661 tempC*(-9.585e-2 +
662 tempC*(8.74e-4 -
663 tempC*5.044e-7))) / 1.0e6;
664 return 1 / (xlCO2 * V_phi/M_T + M_H2O * xlH2O / (rho_pure * M_T));
665 }
666
671 template <class LhsEval>
672 OPM_HOST_DEVICE LhsEval convertRsToXoG_(const LhsEval& Rs, unsigned regionIdx) const
673 {
674 OPM_TIMEFUNCTION_LOCAL(Subsystem::PvtProps);
675 Scalar rho_oRef = brineReferenceDensity_[regionIdx];
676 Scalar rho_gRef = co2ReferenceDensity_[regionIdx];
677
678 const LhsEval& rho_oG = Rs*rho_gRef;
679 return rho_oG/(rho_oRef + rho_oG);
680 }
681
685 template <class LhsEval>
686 OPM_HOST_DEVICE LhsEval convertXoGToxoG_(const LhsEval& XoG, const LhsEval& salinity) const
687 {
688 OPM_TIMEFUNCTION_LOCAL(Subsystem::PvtProps);
689 Scalar M_CO2 = CO2::molarMass();
690 LhsEval M_Brine = Brine::molarMass(salinity);
691 return XoG*M_Brine / (M_CO2*(1 - XoG) + XoG*M_Brine);
692 }
693
697 template <class LhsEval>
698 OPM_HOST_DEVICE LhsEval convertxoGToXoG(const LhsEval& xoG, const LhsEval& salinity) const
699 {
700 OPM_TIMEBLOCK_LOCAL(convertxoGToXoG, Subsystem::PvtProps);
701 Scalar M_CO2 = CO2::molarMass();
702 LhsEval M_Brine = Brine::molarMass(salinity);
703
704 return xoG*M_CO2 / (xoG*(M_CO2 - M_Brine) + M_Brine);
705 }
706
711 template <class LhsEval>
712 OPM_HOST_DEVICE LhsEval convertXoGToRs(const LhsEval& XoG, unsigned regionIdx) const
713 {
714 Scalar rho_oRef = brineReferenceDensity_[regionIdx];
715 Scalar rho_gRef = co2ReferenceDensity_[regionIdx];
716
717 return XoG/(1.0 - XoG)*(rho_oRef/rho_gRef);
718 }
719
720 template <class LhsEval>
721 OPM_HOST_DEVICE LhsEval liquidEnthalpyBrineCO2_(const LhsEval& T,
722 const LhsEval& p,
723 const LhsEval& salinity,
724 const LhsEval& X_CO2_w) const
725 {
726 if (liquidMixType_ == Co2StoreConfig::LiquidMixingType::NONE
727 && saltMixType_ == Co2StoreConfig::SaltMixingType::NONE)
728 {
729 return H2O::liquidEnthalpy(T, p);
730 }
731
732 LhsEval hw = H2O::liquidEnthalpy(T, p) /1E3; /* kJ/kg */
733 LhsEval h_ls1 = hw;
734 // Use mixing model for salt by MICHAELIDES
735 if (saltMixType_ == Co2StoreConfig::SaltMixingType::MICHAELIDES) {
736
737 /* X_CO2_w : mass fraction of CO2 in brine */
738
739 /* same function as enthalpy_brine, only extended by CO2 content */
740
741 /*Numerical coefficents from PALLISER*/
742 static constexpr Scalar f[] = {
743 2.63500E-1, 7.48368E-6, 1.44611E-6, -3.80860E-10
744 };
745
746 /*Numerical coefficents from MICHAELIDES for the enthalpy of brine*/
747 static constexpr Scalar a[4][3] = {
748 { 9633.6, -4080.0, +286.49 },
749 { +166.58, +68.577, -4.6856 },
750 { -0.90963, -0.36524, +0.249667E-1 },
751 { +0.17965E-2, +0.71924E-3, -0.4900E-4 }
752 };
753
754 LhsEval theta, h_NaCl;
755 LhsEval d_h, delta_h;
756
757 theta = T - 273.15;
758
759 // Regularization
760 Scalar scalarTheta = scalarValue(theta);
761 Scalar S_lSAT = f[0] + scalarTheta*(f[1] + scalarTheta*(f[2] + scalarTheta*f[3]));
762
763 LhsEval S = salinity;
764 if (S > S_lSAT)
765 S = S_lSAT;
766
767 /*DAUBERT and DANNER*/
768 /*U=*/h_NaCl = (3.6710E4*T + 0.5*(6.2770E1)*T*T - ((6.6670E-2)/3)*T*T*T
769 +((2.8000E-5)/4)*(T*T*T*T))/(58.44E3)- 2.045698e+02; /* kJ/kg */
770
771 LhsEval m = 1E3 / 58.44 * S / (1 - S);
772 d_h = 0;
773
774 for (int i = 0; i <=3; ++i) {
775 for (int j = 0; j <= 2; ++j) {
776 d_h += a[i][j] * pow(theta, static_cast<Scalar>(i)) * pow(m, j);
777 }
778 }
779 /* heat of dissolution for halite according to Michaelides 1971 */
780 delta_h = (4.184/(1E3 + (58.44 * m)))*d_h;
781
782 /* Enthalpy of brine without CO2 */
783 h_ls1 =(1-S)*hw + S*h_NaCl + S*delta_h; /* kJ/kg */
784
785 // Use Enthalpy of brine without CO2
786 if (liquidMixType_ == Co2StoreConfig::LiquidMixingType::NONE) {
787 return h_ls1*1E3;
788 }
789 }
790
791 LhsEval delta_hCO2, hg;
792 /* heat of dissolution for CO2 according to Fig. 6 in Duan and Sun 2003. (kJ/kg)
793 In the relevant temperature ranges CO2 dissolution is
794 exothermal */
795 if (liquidMixType_ == Co2StoreConfig::LiquidMixingType::DUANSUN) {
796 delta_hCO2 = (-57.4375 + T * 0.1325) * 1000/44;
797 }
798 else {
799 delta_hCO2 = 0.0;
800 }
801
802 /* enthalpy contribution of CO2 (kJ/kg) */
803 hg = CO2::gasEnthalpy(co2Tables_, T, p, extrapolate)/1E3 + delta_hCO2;
804
805 /* Enthalpy of brine with dissolved CO2 */
806 return (h_ls1 - X_CO2_w*hw + hg*X_CO2_w)*1E3; /*J/kg*/
807 }
808
809 template <class LhsEval>
810 OPM_HOST_DEVICE const LhsEval salinityFromConcentration(unsigned regionIdx,
811 const LhsEval&T,
812 const LhsEval& P,
813 const LhsEval& saltConcentration) const
814 {
815 if (enableSaltConcentration_) {
816 return saltConcentration/H2O::liquidDensity(T, P, true);
817 }
818
819 return salinity(regionIdx);
820 }
821
822 #if HAVE_CUDA
823 template <class ScalarT>
824 friend BrineCo2Pvt<ScalarT, gpuistl::GpuView>
825 gpuistl::make_view(BrineCo2Pvt<ScalarT, gpuistl::GpuBuffer>&);
826 #endif
827
828 ContainerT brineReferenceDensity_{};
829 ContainerT co2ReferenceDensity_{};
830 ContainerT salinity_{};
831 ContainerT ezrokhiDenNaClCoeff_{};
832 ContainerT ezrokhiDenCo2Coeff_{};
833 ContainerT ezrokhiViscNaClCoeff_{};
834 bool enableEzrokhiDensity_ = false;
835 bool enableEzrokhiViscosity_ = false;
836 bool enableDissolution_ = true;
837 bool enableSaltConcentration_ = false;
838 int activityModel_{};
839 Co2StoreConfig::LiquidMixingType liquidMixType_{};
840 Co2StoreConfig::SaltMixingType saltMixType_{};
841 Params co2Tables_;
842};
843
844} // namespace Opm
845
846#if HAVE_CUDA
847namespace Opm::gpuistl
848{
849
850 template<class ScalarT>
851 BrineCo2Pvt<ScalarT, GpuBuffer>
852 copy_to_gpu(const BrineCo2Pvt<ScalarT>& cpuBrineCo2)
853 {
854 return BrineCo2Pvt<ScalarT, GpuBuffer>(
855 GpuBuffer<ScalarT>(cpuBrineCo2.getBrineReferenceDensity()),
856 GpuBuffer<ScalarT>(cpuBrineCo2.getCo2ReferenceDensity()),
857 GpuBuffer<ScalarT>(cpuBrineCo2.getSalinity()),
858 cpuBrineCo2.getActivityModel(),
859 cpuBrineCo2.getThermalMixingModelSalt(),
860 cpuBrineCo2.getThermalMixingModelLiquid(),
861 copy_to_gpu(cpuBrineCo2.getParams())
862 );
863 }
864
865 template <class ScalarT>
866 BrineCo2Pvt<ScalarT, GpuView>
867 make_view(BrineCo2Pvt<ScalarT, GpuBuffer>& brineCo2Pvt)
868 {
869
870 using ContainedType = ScalarT;
871
872 auto newBrineReferenceDensity = make_view<ContainedType>(brineCo2Pvt.brineReferenceDensity_);
873 auto newGasReferenceDensity = make_view<ContainedType>(brineCo2Pvt.co2ReferenceDensity_);
874 auto newSalinity = make_view<ContainedType>(brineCo2Pvt.salinity_);
875
876 return BrineCo2Pvt<ScalarT, GpuView>(
877 newBrineReferenceDensity,
878 newGasReferenceDensity,
879 newSalinity,
880 brineCo2Pvt.getActivityModel(),
881 brineCo2Pvt.getThermalMixingModelSalt(),
882 brineCo2Pvt.getThermalMixingModelLiquid(),
883 make_view(brineCo2Pvt.co2Tables_)
884 );
885 }
886} // namespace Opm::gpuistl
887#endif // HAVE_CUDA
888
889#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.
PiecewiseLinearTwoPhaseMaterialParams< TraitsT, GPUContainerType > copy_to_gpu(const PiecewiseLinearTwoPhaseMaterialParams< TraitsT > &params)
Move a PiecewiseLinearTwoPhaseMaterialParams-object to the GPU.
Definition PiecewiseLinearTwoPhaseMaterialParams.hpp:285
PiecewiseLinearTwoPhaseMaterialParams< TraitsT, ViewType > make_view(PiecewiseLinearTwoPhaseMaterialParams< TraitsT, ContainerType > &params)
this function is intented to make a GPU friendly view of the PiecewiseLinearTwoPhaseMaterialParams
Definition PiecewiseLinearTwoPhaseMaterialParams.hpp:312
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:111
This class represents the Pressure-Volume-Temperature relations of the liquid phase for a CO2-Brine s...
Definition BrineCo2Pvt.hpp:80
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:438
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:384
void setActivityModelSalt(int activityModel)
Set activity coefficient model for salt in solubility model.
Definition BrineCo2Pvt.cpp:173
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:258
void setEnableDissolvedGas(bool yesno)
Specify whether the PVT model should consider that the CO2 component can dissolve in the brine phase.
Definition BrineCo2Pvt.hpp:168
void initEnd()
Finish initializing the oil phase PVT properties.
Definition BrineCo2Pvt.hpp:158
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:315
void setThermalMixingModel(int thermalMixingModelSalt, int thermalMixingModelLiquid)
Set thermal mixing model for co2 in brine.
Definition BrineCo2Pvt.cpp:185
void setEnableSaltConcentration(bool yesno)
Specify whether the PVT model should consider salt concentration from the fluidstate or a fixed salin...
Definition BrineCo2Pvt.hpp:177
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:332
BinaryCoeff::Brine_CO2< Scalar, H2O, CO2 > BinaryCoeffBrineCO2
The binary coefficients for brine and CO2 used by this fluid system.
Definition BrineCo2Pvt.hpp:99
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:227
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:349
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:279
std::pair< LhsEval, LhsEval > inverseFormationVolumeFactorAndViscosity(const FluidState &fluidState, unsigned regionIdx)
Returns the formation volume factor [-] and viscosity [Pa s] of the fluid phase.
Definition BrineCo2Pvt.hpp:364
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:208
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:245
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:421
unsigned numRegions() const
Return the number of PVT regions which are considered by this PVT-object.
Definition BrineCo2Pvt.hpp:197
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
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:452
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:402
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:294
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:466
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 liquid viscosity of the pure component.
Definition BrineDynamic.hpp:385
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:283
Definition CO2Tables.hpp:63
A class for the CO2 fluid properties.
Definition CO2.hpp:58
static OPM_HOST_DEVICE Scalar molarMass()
Definition CO2.hpp:73
static OPM_HOST_DEVICE Evaluation gasEnthalpy(const Params &params, const Evaluation &temperature, const Evaluation &pressure, bool extrapolate=false)
Definition CO2.hpp:171
Definition Co2StoreConfig.hpp:33
static Scalar molarMass()
Definition Component.hpp:93
Definition EclipseState.hpp:62
Definition EzrokhiTable.hpp:57
Definition Schedule.hpp:101
A simple version of pure water with density from Hu et al.
Definition SimpleHuDuanH2O.hpp:66
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:316
static OPM_HOST_DEVICE Evaluation liquidViscosity(const Evaluation &temperature, const Evaluation &pressure, bool extrapolate)
The dynamic viscosity of pure water.
Definition SimpleHuDuanH2O.hpp:361
static OPM_HOST_DEVICE Scalar molarMass()
The molar mass in of water.
Definition SimpleHuDuanH2O.hpp:103
static OPM_HOST_DEVICE Evaluation liquidEnthalpy(const Evaluation &temperature, const Evaluation &)
Specific enthalpy of liquid water .
Definition SimpleHuDuanH2O.hpp:202
Convience header to include the gpuistl headers if HAVE_CUDA is defined.
This class implements a small container which holds the transmissibility mulitpliers for all the face...
Definition Exceptions.hpp:30
Scalar Brine< Scalar, H2O >::salinity
Default value for the salinity of the brine (dimensionless).
Definition Brine.hpp:391