blackoilprimaryvariables.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 This file is part of the Open Porous Media project (OPM).
5 OPM is free software: you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation, either version 2 of the License, or
8 (at your option) any later version.
9 OPM is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
13 You should have received a copy of the GNU General Public License
14 along with OPM. If not, see <http://www.gnu.org/licenses/>.
15 Consult the COPYING file in the top-level source directory of this
16 module for the precise wording of the license and the list of
17 copyright holders.
18*/
24#ifndef EWOMS_BLACK_OIL_PRIMARY_VARIABLES_HH
25#define EWOMS_BLACK_OIL_PRIMARY_VARIABLES_HH
26
27#include <dune/common/fvector.hh>
28#include <opm/common/OpmLog/OpmLog.hpp>
29#include <opm/common/utility/gpuDecorators.hpp>
30
31#include <opm/material/common/MathToolbox.hpp>
32#include <opm/material/common/Valgrind.hpp>
33#include <opm/material/fluidsystems/BlackOilFluidSystem.hpp>
34#include <opm/material/fluidstates/SimpleModularFluidState.hpp>
35
43
45
46#include <fmt/format.h>
47
48#include <algorithm>
49#include <array>
50#include <cassert>
51#include <cstddef>
52#include <stdexcept>
53#include <type_traits>
54
55namespace Opm::Parameters {
56
57template<class Scalar>
59{ static constexpr Scalar value = 1.0; };
60
61} // namespace Opm::Parameters
62
63namespace Opm {
64
70template <class TypeTag, template<class, int> class VectorType = Dune::FieldVector>
71class BlackOilPrimaryVariables : public FvBasePrimaryVariables<TypeTag, VectorType>
72{
75
83
84 // number of equations
85 enum { numEq = getPropValue<TypeTag, Properties::NumEq>() };
86
87 // primary variable indices
88 enum { waterSwitchIdx = Indices::waterSwitchIdx };
89 enum { pressureSwitchIdx = Indices::pressureSwitchIdx };
90 enum { compositionSwitchIdx = Indices::compositionSwitchIdx };
91 enum { saltConcentrationIdx = Indices::saltConcentrationIdx };
92 enum { solventSaturationIdx = Indices::solventSaturationIdx };
93
94 static constexpr bool compositionSwitchEnabled = Indices::compositionSwitchIdx >= 0;
95 static constexpr bool waterEnabled = Indices::waterEnabled;
96 static constexpr bool gasEnabled = Indices::gasEnabled;
97 static constexpr bool oilEnabled = Indices::oilEnabled;
98
99 // phase indices from the fluid system
100 enum { numPhases = getPropValue<TypeTag, Properties::NumPhases>() };
101 enum { gasPhaseIdx = FluidSystem::gasPhaseIdx };
102 enum { waterPhaseIdx = FluidSystem::waterPhaseIdx };
103 enum { oilPhaseIdx = FluidSystem::oilPhaseIdx };
104
105 // component indices from the fluid system
106 enum { numComponents = getPropValue<TypeTag, Properties::NumComponents>() };
107 enum { enableSolvent = getPropValue<TypeTag, Properties::EnableSolvent>() };
108 enum { enableExtbo = getPropValue<TypeTag, Properties::EnableExtbo>() };
109 enum { enablePolymer = getPropValue<TypeTag, Properties::EnablePolymer>() };
110 enum { enableFoam = getPropValue<TypeTag, Properties::EnableFoam>() };
111 enum { enableBrine = getPropValue<TypeTag, Properties::EnableBrine>() };
112 enum { enableSaltPrecipitation = getPropValue<TypeTag, Properties::EnableSaltPrecipitation>() };
113 enum { enableVapwat = getPropValue<TypeTag, Properties::EnableVapwat>() };
114 static constexpr EnergyModules energyModuleType = getPropValue<TypeTag, Properties::EnergyModuleType>();
115 enum { enableEnergy = (energyModuleType == EnergyModules::FullyImplicitThermal) };
116 enum { enableTemperature = (energyModuleType == EnergyModules::ConstantTemperature) };
117 enum { enableBioeffects = getPropValue<TypeTag, Properties::EnableBioeffects>() };
118 enum { enableMICP = Indices::enableMICP };
119 enum { gasCompIdx = FluidSystem::gasCompIdx };
120 enum { waterCompIdx = FluidSystem::waterCompIdx };
121 enum { oilCompIdx = FluidSystem::oilCompIdx };
122
123 using Toolbox = MathToolbox<Evaluation>;
124 using ComponentVector = Dune::FieldVector<Scalar, numComponents>;
130
131 static_assert(numPhases == 3, "The black-oil model assumes three phases!");
132 static_assert(numComponents == 3, "The black-oil model assumes three components!");
133
134public:
135 // We are instantiating this class with different TypeTags and VectorTypes,
136 // but we still want to be able to copy between them. Therefore, we
137 // need to define the same type aliases in all specializations.
143
144 // Allow conversion between different vector types
145 template<class OtherTypeTag, template<class, int> class OtherVectorType>
147
151 template <class OtherTypeTag, template <class, int> class OtherVectorType>
152 explicit OPM_HOST_DEVICE
154 : ParentType(other)
155 , primaryVarsMeaningWater_(other.primaryVarsMeaningWater_)
156 , primaryVarsMeaningPressure_(other.primaryVarsMeaningPressure_)
157 , primaryVarsMeaningGas_(other.primaryVarsMeaningGas_)
158 , primaryVarsMeaningBrine_(other.primaryVarsMeaningBrine_)
159 , primaryVarsMeaningSolvent_(other.primaryVarsMeaningSolvent_)
160 , pvtRegionIdx_(other.pvtRegionIdx_)
161 , pcFactor_(other.pcFactor_)
162 {
163 }
164
165 OPM_HOST_DEVICE BlackOilPrimaryVariables()
166 {
167 Valgrind::SetUndefined(*this);
168 pvtRegionIdx_ = 0;
169 }
170
175
177 {
179 result.pvtRegionIdx_ = 1;
180 result.primaryVarsMeaningBrine_ = BrineMeaning::Sp;
181 result.primaryVarsMeaningGas_ = GasMeaning::Rv;
182 result.primaryVarsMeaningPressure_ = PressureMeaning::Pg;
183 result.primaryVarsMeaningWater_ = WaterMeaning::Rsw;
184 result.primaryVarsMeaningSolvent_ = SolventMeaning::Ss;
185 for (std::size_t i = 0; i < result.size(); ++i) {
186 result[i] = i + 1;
187 }
188
189 return result;
190 }
191
192 static void init()
193 {
194 // TODO: these parameters have undocumented non-trivial dependencies
195 pressureScale_ = Parameters::Get<Parameters::PressureScale<Scalar>>();
196
197// currently for GPU we do not have a support for the pressureScale_ variable,
198// so we issue a warning if the user has set it to something else than 1.0
199// if we are building with GPU support. Note that we can not only test if we are compiling
200// with a GPU compiler, because we might initialize the parameters from a .cpp compilation unit
201// compiled by a normal C++ compiler.
202#if HAVE_CUDA
203 if (pressureScale_ != Scalar {1.0}) {
204 OpmLog::warning(fmt::format(
205 "Using a pressure scaling different from 1.0 is not supported "
206 "when running with GPU support. We have detected that you are compiling with GPU support, but we can "
207 "not detect whether you are running with GPU support for the assembly or property evaluation. If you "
208 "are doing property evaluation or assembly on the GPU, pressure scaling will be ignored."
209 "Read value of pressure scale: {}",
210 pressureScale_));
211 }
212#endif
213 }
214
215 static void registerParameters()
216 {
217 Parameters::Register<Parameters::PressureScale<Scalar>>
218 ("Scaling of pressure primary variable");
219 }
220
221 OPM_HOST_DEVICE Evaluation
222 makeEvaluation(unsigned varIdx, unsigned timeIdx,
223 LinearizationType linearizationType = LinearizationType()) const
224 {
225 const Scalar scale = varIdx == pressureSwitchIdx ? this->getPressureScale() : Scalar{1.0};
226 if (std::is_same_v<Evaluation, Scalar>) {
227 return (*this)[varIdx] * scale; // finite differences
228 }
229 else {
230 // automatic differentiation
231 if (timeIdx == linearizationType.time) {
232 return Toolbox::createVariable((*this)[varIdx], varIdx) * scale;
233 }
234 else {
235 return Toolbox::createConstant((*this)[varIdx]) * scale;
236 }
237 }
238 }
239
247 OPM_HOST_DEVICE void setPvtRegionIndex(unsigned value)
248 { pvtRegionIdx_ = static_cast<unsigned short>(value); }
249
253 OPM_HOST_DEVICE unsigned pvtRegionIndex() const
254 { return pvtRegionIdx_; }
255
260 OPM_HOST_DEVICE WaterMeaning primaryVarsMeaningWater() const
261 { return primaryVarsMeaningWater_; }
262
267 OPM_HOST_DEVICE void setPrimaryVarsMeaningWater(WaterMeaning newMeaning)
268 { primaryVarsMeaningWater_ = newMeaning; }
269
275 { return primaryVarsMeaningPressure_; }
276
281 OPM_HOST_DEVICE void setPrimaryVarsMeaningPressure(PressureMeaning newMeaning)
282 { primaryVarsMeaningPressure_ = newMeaning; }
283
288 OPM_HOST_DEVICE GasMeaning primaryVarsMeaningGas() const
289 { return primaryVarsMeaningGas_; }
290
295 OPM_HOST_DEVICE void setPrimaryVarsMeaningGas(GasMeaning newMeaning)
296 { primaryVarsMeaningGas_ = newMeaning; }
297
298 OPM_HOST_DEVICE BrineMeaning primaryVarsMeaningBrine() const
299 { return primaryVarsMeaningBrine_; }
300
305 OPM_HOST_DEVICE void setPrimaryVarsMeaningBrine(BrineMeaning newMeaning)
306 { primaryVarsMeaningBrine_ = newMeaning; }
307
309 { return primaryVarsMeaningSolvent_; }
310
315 OPM_HOST_DEVICE void setPrimaryVarsMeaningSolvent(SolventMeaning newMeaning)
316 { primaryVarsMeaningSolvent_ = newMeaning; }
317
321 template <class FluidState>
322 OPM_HOST_DEVICE void assignNaive(const FluidState& fluidState)
323 {
324 using ConstEvaluation = std::remove_reference_t<typename FluidState::Scalar>;
325 using FsEvaluation = std::remove_const_t<ConstEvaluation>;
326 using FsToolbox = MathToolbox<FsEvaluation>;
327
328 const bool gasPresent =
329 fluidState.fluidSystem().phaseIsActive(gasPhaseIdx)
330 ? fluidState.saturation(gasPhaseIdx) > 0.0
331 : false;
332 const bool oilPresent =
333 fluidState.fluidSystem().phaseIsActive(oilPhaseIdx)
334 ? fluidState.saturation(oilPhaseIdx) > 0.0
335 : false;
336 const bool waterPresent =
337 fluidState.fluidSystem().phaseIsActive(waterPhaseIdx)
338 ? fluidState.saturation(waterPhaseIdx) > 0.0
339 : false;
340 const auto& saltSaturation =
341 BlackOil::getSaltSaturation_<FluidSystem, FluidState, Scalar>(fluidState, pvtRegionIdx_);
342 const bool precipitatedSaltPresent = enableSaltPrecipitation ? saltSaturation > 0.0 : false;
343 const bool oneActivePhases = fluidState.fluidSystem().numActivePhases() == 1;
344 // deal with the primary variables for the energy extension
345 EnergyModule::assignPrimaryVars(*this, fluidState);
346
347 // Determine the meaning of the pressure primary variables
348 // Depending on the phases present, this variable is either interpreted as the
349 // pressure of the oil phase, gas phase (if no oil) or water phase (if only water)
350 if (gasPresent && fluidState.fluidSystem().enableVaporizedOil() && !oilPresent) {
351 primaryVarsMeaningPressure_ = PressureMeaning::Pg;
352 }
353 else if (fluidState.fluidSystem().phaseIsActive(oilPhaseIdx)) {
354 primaryVarsMeaningPressure_ = PressureMeaning::Po;
355 }
356 else if (waterPresent && fluidState.fluidSystem().enableDissolvedGasInWater() && !gasPresent) {
357 primaryVarsMeaningPressure_ = PressureMeaning::Pw;
358 }
359 else if (fluidState.fluidSystem().phaseIsActive(gasPhaseIdx)) {
360 primaryVarsMeaningPressure_ = PressureMeaning::Pg;
361 }
362 else {
363 assert(fluidState.fluidSystem().phaseIsActive(waterPhaseIdx));
364 primaryVarsMeaningPressure_ = PressureMeaning::Pw;
365 }
366
367 // Determine the meaning of the water primary variables
368 // Depending on the phases present, this variable is either interpreted as
369 // water saturation or vapporized water in the gas phase
370 // For two-phase gas-oil models and one-phase case the variable is disabled.
371 if (waterPresent && gasPresent) {
372 primaryVarsMeaningWater_ = WaterMeaning::Sw;
373 }
374 else if (gasPresent && fluidState.fluidSystem().enableVaporizedWater()) {
375 primaryVarsMeaningWater_ = WaterMeaning::Rvw;
376 }
377 else if (waterPresent && fluidState.fluidSystem().enableDissolvedGasInWater()) {
378 primaryVarsMeaningWater_ = WaterMeaning::Rsw;
379 }
380 else if (fluidState.fluidSystem().phaseIsActive(waterPhaseIdx) && !oneActivePhases) {
381 primaryVarsMeaningWater_ = WaterMeaning::Sw;
382 }
383 else {
384 primaryVarsMeaningWater_ = WaterMeaning::Disabled;
385 }
386
387 // Determine the meaning of the gas primary variables
388 // Depending on the phases present, this variable is either interpreted as the
389 // saturation of the gas phase, as the fraction of the gas component in the oil
390 // phase (Rs) or as the fraction of the oil component (Rv) in the gas phase.
391 // For two-phase water-oil and water-gas models and one-phase case the variable is disabled.
392 if (gasPresent && oilPresent) {
393 primaryVarsMeaningGas_ = GasMeaning::Sg;
394 }
395 else if (oilPresent && fluidState.fluidSystem().enableDissolvedGas()) {
396 primaryVarsMeaningGas_ = GasMeaning::Rs;
397 }
398 else if (gasPresent && fluidState.fluidSystem().enableVaporizedOil()) {
399 primaryVarsMeaningGas_ = GasMeaning::Rv;
400 }
401 else if (fluidState.fluidSystem().phaseIsActive(gasPhaseIdx) && fluidState.fluidSystem().phaseIsActive(oilPhaseIdx)) {
402 primaryVarsMeaningGas_ = GasMeaning::Sg;
403 }
404 else {
405 primaryVarsMeaningGas_ = GasMeaning::Disabled;
406 }
407
408 // Determine the meaning of the brine primary variables
409 if constexpr (enableSaltPrecipitation) {
410 if (precipitatedSaltPresent) {
411 primaryVarsMeaningBrine_ = BrineMeaning::Sp;
412 }
413 else {
414 primaryVarsMeaningBrine_ = BrineMeaning::Cs;
415 }
416 }
417 else {
418 primaryVarsMeaningBrine_ = BrineMeaning::Disabled;
419 }
420
421 // assign the actual primary variables
422 switch (primaryVarsMeaningPressure()) {
423 case PressureMeaning::Po:
424 this->setScaledPressure_(FsToolbox::value(fluidState.pressure(oilPhaseIdx)));
425 break;
426 case PressureMeaning::Pg:
427 this->setScaledPressure_(FsToolbox::value(fluidState.pressure(gasPhaseIdx)));
428 break;
429 case PressureMeaning::Pw:
430 this->setScaledPressure_(FsToolbox::value(fluidState.pressure(waterPhaseIdx)));
431 break;
432 default:
433 OPM_THROW(std::logic_error, "No valid primary variable selected for pressure");
434 }
435
436 switch (primaryVarsMeaningWater()) {
437 case WaterMeaning::Sw:
438 {
439 (*this)[waterSwitchIdx] = FsToolbox::value(fluidState.saturation(waterPhaseIdx));
440 break;
441 }
442 case WaterMeaning::Rvw:
443 {
444 const auto& rvw = BlackOil::getRvw_<FluidSystem, FluidState, Scalar>(fluidState, pvtRegionIdx_);
445 (*this)[waterSwitchIdx] = rvw;
446 break;
447 }
448 case WaterMeaning::Rsw:
449 {
450 const auto& Rsw = BlackOil::getRsw_<FluidSystem, FluidState, Scalar>(fluidState, pvtRegionIdx_);
451 (*this)[waterSwitchIdx] = Rsw;
452 break;
453 }
454 case WaterMeaning::Disabled:
455 break;
456 default:
457 OPM_THROW(std::logic_error, "No valid primary variable selected for water");
458 }
459 switch (primaryVarsMeaningGas()) {
460 case GasMeaning::Sg:
461 (*this)[compositionSwitchIdx] = FsToolbox::value(fluidState.saturation(gasPhaseIdx));
462 break;
463 case GasMeaning::Rs:
464 {
465 const auto& rs = BlackOil::getRs_<FluidSystem, FluidState, Scalar>(fluidState, pvtRegionIdx_);
466 (*this)[compositionSwitchIdx] = rs;
467 break;
468 }
469 case GasMeaning::Rv:
470 {
471 const auto& rv = BlackOil::getRv_<FluidSystem, FluidState, Scalar>(fluidState, pvtRegionIdx_);
472 (*this)[compositionSwitchIdx] = rv;
473 break;
474 }
475 case GasMeaning::Disabled:
476 break;
477 default:
478 OPM_THROW(std::logic_error, "No valid primary variable selected for composision");
479 }
480 }
481
493 bool adaptPrimaryVariables(const Problem& problem,
494 unsigned globalDofIdx,
495 [[maybe_unused]] Scalar swMaximum,
496 Scalar thresholdWaterFilledCell, Scalar eps = 0.0)
497 {
498 // this function accesses quite a few black-oil specific low-level functions
499 // directly for better performance (instead of going the canonical way through
500 // the IntensiveQuantities). The reason is that most intensive quantities are not
501 // required to be able to decide if the primary variables needs to be switched or
502 // not, so it would be a waste to compute them.
503
504 // Both the primary variable meaning of water and gas are disabled i.e.
505 // It is a one-phase case and we no variable meaning switch is needed.
506 if (primaryVarsMeaningWater() == WaterMeaning::Disabled &&
507 primaryVarsMeaningGas() == GasMeaning::Disabled)
508 {
509 return false;
510 }
511
512 // Read the current saturation from the primary variables
513 Scalar sw = 0.0;
514 Scalar sg = 0.0;
515 Scalar saltConcentration = 0.0;
516 const Scalar& T = asImp_().temperature_(problem, globalDofIdx);
518 sw = (*this)[waterSwitchIdx];
519 }
521 sg = (*this)[compositionSwitchIdx];
522 }
523 if (primaryVarsMeaningWater() == WaterMeaning::Rsw) {
524 sw = 1.0;
525 }
526
527 if (primaryVarsMeaningGas() == GasMeaning::Disabled && gasEnabled) {
528 sg = 1.0 - sw; // water + gas case
529 }
530
531 // if solid phase disappeares: Sp (Solid salt saturation) -> Cs (salt concentration)
532 // if solid phase appears: Cs (salt concentration) -> Sp (Solid salt saturation)
533 if constexpr (enableSaltPrecipitation) {
534 const Scalar saltSolubility = BrineModule::saltSol(pvtRegionIndex());
535 if (primaryVarsMeaningBrine() == BrineMeaning::Sp) {
536 saltConcentration = saltSolubility;
537 const Scalar saltSat = (*this)[saltConcentrationIdx];
538 if (saltSat < -eps) { // precipitated salt dissappears
539 setPrimaryVarsMeaningBrine(BrineMeaning::Cs);
540 (*this)[saltConcentrationIdx] = saltSolubility; // set salt concentration to solubility limit
541 }
542 }
543 else if (primaryVarsMeaningBrine() == BrineMeaning::Cs) {
544 saltConcentration = (*this)[saltConcentrationIdx];
545 if (saltConcentration > saltSolubility + eps) { // salt concentration exceeds solubility limit
546 setPrimaryVarsMeaningBrine(BrineMeaning::Sp);
547 (*this)[saltConcentrationIdx] = 0.0;
548 }
549 }
550 }
551
552 // if solvent saturation disappeares: Ss (Solvent saturation) -> Rsolw (solvent dissolved in water)
553 // if solvent saturation appears: Rsolw (solvent dissolved in water) -> Ss (Solvent saturation)
554 // Scalar rsolw = 0.0; // not needed at the moment since we dont allow for vapwat in combination with rsolw
555 if constexpr (enableSolvent) {
557 const Scalar p = (*this)[pressureSwitchIdx]; // cap-pressure?
558 const Scalar solLimit =
559 SolventModule::solubilityLimit(pvtRegionIndex(), T , p, saltConcentration);
560 if (primaryVarsMeaningSolvent() == SolventMeaning::Ss) {
561 const Scalar solSat = (*this)[solventSaturationIdx];
562 if (solSat < -eps) { // solvent dissappears
563 setPrimaryVarsMeaningSolvent(SolventMeaning::Rsolw);
564 (*this)[solventSaturationIdx] = solLimit; // set rsolw to solubility limit
565 }
566 }
567 else if (primaryVarsMeaningSolvent() == SolventMeaning::Rsolw) {
568 const Scalar rsolw = (*this)[solventSaturationIdx];
569 if (rsolw > solLimit + eps) { // solvent appears as phase
570 setPrimaryVarsMeaningSolvent(SolventMeaning::Ss);
571 (*this)[solventSaturationIdx] = 0.0;
572 }
573 }
574 }
575 }
576
577 // keep track if any meaning has changed
578 bool changed = false;
579
580 // Special case for cells with almost only water
581 // for these cells both saturations (if the phase is enabled) is used
582 // to avoid singular systems.
583 // If dissolved gas in water is enabled we shouldn't enter
584 // here but instead switch to Rsw as primary variable
585 // as sw >= 1.0 -> gas <= 0 (i.e. gas phase disappears)
586 if (sw >= thresholdWaterFilledCell && !FluidSystem::enableDissolvedGasInWater()) {
587 // make sure water saturations does not exceed sw_maximum. Default to 1.0
588 if constexpr (waterEnabled) {
589 (*this)[Indices::waterSwitchIdx] = std::min(swMaximum, sw);
591 }
592 // the hydrocarbon gas saturation is set to 0.0
593 if constexpr (compositionSwitchEnabled) {
594 (*this)[Indices::compositionSwitchIdx] = 0.0;
595 }
596
598 if (changed) {
599 if constexpr (compositionSwitchEnabled) {
601 }
602
603 // use water pressure?
604 }
605 return changed;
606 }
607
608 pcFactor_ = 1.0;
609 if constexpr (enableBrine) {
610 if (BrineModule::hasPcfactTables() && primaryVarsMeaningBrine() == BrineMeaning::Sp) {
611 unsigned satnumRegionIdx = problem.satnumRegionIndex(globalDofIdx);
612 Scalar Sp = saltConcentration_();
613 Scalar porosityFactor = std::min(1.0 - Sp, 1.0); //phi/phi_0
614 const auto& pcfactTable = BrineModule::pcfactTable(satnumRegionIdx);
615 pcFactor_ = pcfactTable.eval(porosityFactor, /*extrapolation=*/true);
616 }
617 }
618 else if constexpr (enableBioeffects) {
619 if (BioeffectsModule::hasPcfactTables() && problem.referencePorosity(globalDofIdx, 0) > 0) {
620 unsigned satnumRegionIdx = problem.satnumRegionIndex(globalDofIdx);
621 Scalar Sb = biofilmVolumeFraction_() /
622 problem.referencePorosity(globalDofIdx, 0);
623 Scalar porosityFactor = std::min(1.0 - Sb, 1.0); //phi/phi_0
624 const auto& pcfactTable = BioeffectsModule::pcfactTable(satnumRegionIdx);
625 pcFactor_ = pcfactTable.eval(porosityFactor, /*extrapolation=*/true);
626 }
627 }
628
629 switch (primaryVarsMeaningWater()) {
630 case WaterMeaning::Sw:
631 {
632 // if water phase disappeares: Sw (water saturation) -> Rvw (fraction of water in gas phase)
633 if (sw < -eps && sg > eps && FluidSystem::enableVaporizedWater()) {
634 Scalar p = this->pressure_();
635 if (primaryVarsMeaningPressure() == PressureMeaning::Po) {
636 std::array<Scalar, numPhases> pC{};
637 const MaterialLawParams& matParams = problem.materialLawParams(globalDofIdx);
638 const Scalar so = 1.0 - sg - solventSaturation_();
639 computeCapillaryPressures_(pC, so, sg + solventSaturation_(), /*sw=*/ 0.0, matParams);
640 p += pcFactor_ * (pC[gasPhaseIdx] - pC[oilPhaseIdx]);
641 }
642 const Scalar rvwSat =
643 FluidSystem::gasPvt().saturatedWaterVaporizationFactor(pvtRegionIdx_,
644 T,
645 p,
646 saltConcentration);
647 setPrimaryVarsMeaningWater(WaterMeaning::Rvw);
648 (*this)[Indices::waterSwitchIdx] = rvwSat; // primary variable becomes Rvw
649 changed = true;
650 break;
651 }
652 // if gas phase disappeares: Sw (water saturation) -> Rsw (fraction of gas in water phase)
653 // and Pg (gas pressure) -> Pw ( water pressure)
654 if (sg < -eps && sw > eps && FluidSystem::enableDissolvedGasInWater()) {
655 const Scalar pg = this->pressure_();
656 assert(primaryVarsMeaningPressure() == PressureMeaning::Pg);
657 std::array<Scalar, numPhases> pC = { 0.0 };
658 const MaterialLawParams& matParams = problem.materialLawParams(globalDofIdx);
659 const Scalar so = 1.0 - sw - solventSaturation_();
660 computeCapillaryPressures_(pC, so, /*sg=*/ 0.0, sw, matParams);
661 const Scalar pw = pg + pcFactor_ * (pC[waterPhaseIdx] - pC[gasPhaseIdx]);
662 const Scalar rswSat =
663 FluidSystem::waterPvt().saturatedGasDissolutionFactor(pvtRegionIdx_,
664 T,
665 pw,
666 saltConcentration);
667 setPrimaryVarsMeaningWater(WaterMeaning::Rsw);
668 const Scalar rswMax = problem.maxGasDissolutionFactor(/*timeIdx=*/0, globalDofIdx);
669 (*this)[Indices::waterSwitchIdx] = std::min(rswSat, rswMax); //primary variable becomes Rsw
670 setPrimaryVarsMeaningPressure(PressureMeaning::Pw);
671 this->setScaledPressure_(pw);
672 changed = true;
673 break;
674 }
675 break;
676 }
677 case WaterMeaning::Rvw:
678 {
679 const Scalar& rvw = (*this)[waterSwitchIdx];
680 Scalar p = this->pressure_();
681 if (primaryVarsMeaningPressure() == PressureMeaning::Po) {
682 std::array<Scalar, numPhases> pC{};
683 const MaterialLawParams& matParams = problem.materialLawParams(globalDofIdx);
684 const Scalar so = 1.0 - sg - solventSaturation_();
685 computeCapillaryPressures_(pC, so, sg + solventSaturation_(), /*sw=*/ 0.0, matParams);
686 p += pcFactor_ * (pC[gasPhaseIdx] - pC[oilPhaseIdx]);
687 }
688 const Scalar rvwSat =
689 FluidSystem::gasPvt().saturatedWaterVaporizationFactor(pvtRegionIdx_,
690 T,
691 p,
692 saltConcentration);
693 // if water phase appears: Rvw (fraction of water in gas phase) -> Sw (water saturation)
694 if (rvw > rvwSat * (1.0 + eps)) {
696 (*this)[Indices::waterSwitchIdx] = 0.0; // water saturation
697 changed = true;
698 }
699 break;
700 }
701 case WaterMeaning::Rsw:
702 {
703 // Gas phase not present. The hydrocarbon gas phase
704 // appears as soon as more of the gas component is present in the water phase
705 // than what saturated water can hold.
706 const Scalar& pw = this->pressure_();
707 assert(primaryVarsMeaningPressure() == PressureMeaning::Pw);
708 const Scalar rswSat =
709 FluidSystem::waterPvt().saturatedGasDissolutionFactor(pvtRegionIdx_,
710 T,
711 pw,
712 saltConcentration);
713
714 const Scalar rsw = (*this)[Indices::waterSwitchIdx];
715 const Scalar rswMax = problem.maxGasDissolutionFactor(/*timeIdx=*/0, globalDofIdx);
716 if (rsw > std::min(rswSat, rswMax)) {
717 // the gas phase appears, i.e., switch the primary variables to WaterMeaning::Sw
719 (*this)[Indices::waterSwitchIdx] = 1.0; // hydrocarbon water saturation
720 setPrimaryVarsMeaningPressure(PressureMeaning::Pg);
721 std::array<Scalar, numPhases> pC{};
722 const MaterialLawParams& matParams = problem.materialLawParams(globalDofIdx);
723 computeCapillaryPressures_(pC, /*so=*/ 0.0, /*sg=*/ 0.0, /*sw=*/ 1.0, matParams);
724 const Scalar pg = pw + pcFactor_ * (pC[gasPhaseIdx] - pC[waterPhaseIdx]);
725 this->setScaledPressure_(pg);
726 changed = true;
727 }
728 break;
729 }
730 case WaterMeaning::Disabled:
731 break;
732 default:
733 throw std::logic_error("No valid primary variable selected for water");
734 }
735
736 // if gas phase disappeares: Sg (gas saturation) -> Rs (fraction of gas in oil phase)
737 // if oil phase disappeares: Sg (gas saturation) -> Rv (fraction of oil in gas phase)
738 // Po (oil pressure ) -> Pg (gas pressure)
739
740 // if gas phase appears: Rs (fraction of gas in oil phase) -> Sg (gas saturation)
741 // if oil phase appears: Rv (fraction of oil in gas phase) -> Sg (gas saturation)
742 // Pg (gas pressure ) -> Po (oil pressure)
743 switch (primaryVarsMeaningGas()) {
744 case GasMeaning::Sg:
745 {
746 const Scalar s = 1.0 - sw - solventSaturation_();
747 if (sg < -eps && s > 0.0 && FluidSystem::enableDissolvedGas()) {
748 const Scalar po = this->pressure_();
750 const Scalar soMax = std::max(s, problem.maxOilSaturation(globalDofIdx));
751 const Scalar rsMax = problem.maxGasDissolutionFactor(/*timeIdx=*/0, globalDofIdx);
752 const Scalar rsSat =
753 enableExtbo
754 ? ExtboModule::rs(pvtRegionIndex(), po, zFraction_())
755 : FluidSystem::oilPvt().saturatedGasDissolutionFactor(pvtRegionIdx_,
756 T,
757 po,
758 s,
759 soMax);
760 (*this)[Indices::compositionSwitchIdx] = std::min(rsMax, rsSat);
761 changed = true;
762 }
763 const Scalar so = 1.0 - sw - solventSaturation_() - sg;
764 if (so < -eps && sg > 0.0 && FluidSystem::enableVaporizedOil()) {
765 // the oil phase disappeared and some hydrocarbon gas phase is still
766 // present, i.e., switch the primary variables to GasMeaning::Rv.
767 // we only have the oil pressure readily available, but we need the gas
768 // pressure, i.e. we must determine capillary pressure
769 const Scalar po = this->pressure_();
770 std::array<Scalar, numPhases> pC{};
771 const MaterialLawParams& matParams = problem.materialLawParams(globalDofIdx);
772 computeCapillaryPressures_(pC, /*so=*/0.0, sg + solventSaturation_(), sw, matParams);
773 const Scalar pg = po + pcFactor_ * (pC[gasPhaseIdx] - pC[oilPhaseIdx]);
774
775 // we start at the GasMeaning::Rv value that corresponds to that of oil-saturated
776 // hydrocarbon gas
777 setPrimaryVarsMeaningPressure(PressureMeaning::Pg);
778 this->setScaledPressure_(pg);
779 const Scalar soMax = problem.maxOilSaturation(globalDofIdx);
780 const Scalar rvMax = problem.maxOilVaporizationFactor(/*timeIdx=*/0, globalDofIdx);
781 const Scalar rvSat =
782 enableExtbo
783 ? ExtboModule::rv(pvtRegionIndex(), pg, zFraction_())
784 : FluidSystem::gasPvt().saturatedOilVaporizationFactor(pvtRegionIdx_,
785 T,
786 pg,
787 Scalar(0),
788 soMax);
790 (*this)[Indices::compositionSwitchIdx] = std::min(rvMax, rvSat);
791 changed = true;
792 }
793 break;
794 }
795 case GasMeaning::Rs:
796 {
797 // Gas phase not present. The hydrocarbon gas phase
798 // appears as soon as more of the gas component is present in the oil phase
799 // than what saturated oil can hold.
800 const Scalar po = this->pressure_();
801 const Scalar so = 1.0 - sw - solventSaturation_();
802 const Scalar soMax = std::max(so, problem.maxOilSaturation(globalDofIdx));
803 const Scalar rsMax = problem.maxGasDissolutionFactor(/*timeIdx=*/0, globalDofIdx);
804 const Scalar rsSat =
805 enableExtbo
806 ? ExtboModule::rs(pvtRegionIndex(), po, zFraction_())
807 : FluidSystem::oilPvt().saturatedGasDissolutionFactor(pvtRegionIdx_,
808 T,
809 po,
810 so,
811 soMax);
812
813 const Scalar rs = (*this)[Indices::compositionSwitchIdx];
814 if (rs > std::min(rsMax, rsSat * (Scalar{1.0} + eps))) {
815 // the gas phase appears, i.e., switch the primary variables to GasMeaning::Sg
817 (*this)[Indices::compositionSwitchIdx] = 0.0; // hydrocarbon gas saturation
818 changed = true;
819 }
820 break;
821 }
822 case GasMeaning::Rv:
823 {
824 // The oil phase appears as
825 // soon as more of the oil component is present in the hydrocarbon gas phase
826 // than what saturated gas contains. Note that we use the blackoil specific
827 // low-level PVT objects here for performance reasons.
828 const Scalar pg = this->pressure_();
829 const Scalar soMax = problem.maxOilSaturation(globalDofIdx);
830 const Scalar rvMax = problem.maxOilVaporizationFactor(/*timeIdx=*/0, globalDofIdx);
831 const Scalar rvSat =
832 enableExtbo
833 ? ExtboModule::rv(pvtRegionIndex(), pg, zFraction_())
834 : FluidSystem::gasPvt().saturatedOilVaporizationFactor(pvtRegionIdx_,
835 T,
836 pg,
837 /*so=*/Scalar(0.0),
838 soMax);
839
840 const Scalar rv = (*this)[Indices::compositionSwitchIdx];
841 if (rv > std::min(rvMax, rvSat * (Scalar{1.0} + eps))) {
842 // switch to phase equilibrium mode because the oil phase appears. here
843 // we also need the capillary pressures to calculate the oil phase
844 // pressure using the gas phase pressure
845 const Scalar sg2 = 1.0 - sw - solventSaturation_();
846 std::array<Scalar, numPhases> pC{};
847 const MaterialLawParams& matParams = problem.materialLawParams(globalDofIdx);
848 computeCapillaryPressures_(pC,
849 /*so=*/0.0,
850 /*sg=*/sg2 + solventSaturation_(),
851 sw,
852 matParams);
853 const Scalar po = pg + pcFactor_ * (pC[oilPhaseIdx] - pC[gasPhaseIdx]);
854
856 setPrimaryVarsMeaningPressure(PressureMeaning::Po);
857 this->setScaledPressure_(po);
858 (*this)[Indices::compositionSwitchIdx] = sg2; // hydrocarbon gas saturation
859 changed = true;
860 }
861 break;
862 }
863 case GasMeaning::Disabled:
864 break;
865 default:
866 throw std::logic_error("No valid primary variable selected for water");
867 }
868 return changed;
869 }
870
871 OPM_HOST_DEVICE bool chopAndNormalizeSaturations()
872 {
873 if (primaryVarsMeaningWater() == WaterMeaning::Disabled &&
874 primaryVarsMeaningGas() == GasMeaning::Disabled)
875 {
876 return false;
877 }
878 Scalar sw = 0.0;
880 sw = (*this)[Indices::waterSwitchIdx];
881 }
882 Scalar sg = 0.0;
884 sg = (*this)[Indices::compositionSwitchIdx];
885 }
886
887 Scalar ssol = 0.0;
888 if (primaryVarsMeaningSolvent() == SolventMeaning::Ss) {
889 ssol =(*this) [Indices::solventSaturationIdx];
890 }
891
892 Scalar so = 1.0 - sw - sg - ssol;
893 sw = std::min(std::max(sw, Scalar{0.0}), Scalar{1.0});
894 so = std::min(std::max(so, Scalar{0.0}), Scalar{1.0});
895 sg = std::min(std::max(sg, Scalar{0.0}), Scalar{1.0});
896 ssol = std::min(std::max(ssol, Scalar{0.0}), Scalar{1.0});
897 const Scalar st = sw + so + sg + ssol;
898 sw = sw / st;
899 sg = sg / st;
900 ssol = ssol / st;
901 assert(st > 0.5);
903 (*this)[Indices::waterSwitchIdx] = sw;
904 }
906 (*this)[Indices::compositionSwitchIdx] = sg;
907 }
908 if (primaryVarsMeaningSolvent() == SolventMeaning::Ss) {
909 (*this) [Indices::solventSaturationIdx] = ssol;
910 }
911
912 return (st != 1);
913 }
914
916
917 using ParentType::operator=;
918
926 OPM_HOST_DEVICE void checkDefined() const
927 {
928#ifndef NDEBUG
929 // check the "real" primary variables
930 for (unsigned i = 0; i < this->size(); ++i) {
931 Valgrind::CheckDefined((*this)[i]);
932 }
933
934 // check the "pseudo" primary variables
935 Valgrind::CheckDefined(primaryVarsMeaningWater_);
936 Valgrind::CheckDefined(primaryVarsMeaningGas_);
937 Valgrind::CheckDefined(primaryVarsMeaningPressure_);
938 Valgrind::CheckDefined(primaryVarsMeaningBrine_);
939 Valgrind::CheckDefined(primaryVarsMeaningSolvent_);
940
941 Valgrind::CheckDefined(pvtRegionIdx_);
942#endif // NDEBUG
943 }
944
945 template<class Serializer>
946 void serializeOp(Serializer& serializer)
947 {
948 using FV = Dune::FieldVector<Scalar, getPropValue<TypeTag, Properties::NumEq>()>;
949 serializer(static_cast<FV&>(*this));
950 serializer(primaryVarsMeaningWater_);
951 serializer(primaryVarsMeaningPressure_);
952 serializer(primaryVarsMeaningGas_);
953 serializer(primaryVarsMeaningBrine_);
954 serializer(primaryVarsMeaningSolvent_);
955 serializer(pvtRegionIdx_);
956 }
957
958 OPM_HOST_DEVICE bool operator==(const BlackOilPrimaryVariables& rhs) const
959 {
960 return
961 static_cast<const FvBasePrimaryVariables<TypeTag>&>(*this) == rhs
962 && this->primaryVarsMeaningWater_ == rhs.primaryVarsMeaningWater_
963 && this->primaryVarsMeaningPressure_ == rhs.primaryVarsMeaningPressure_
964 && this->primaryVarsMeaningGas_ == rhs.primaryVarsMeaningGas_
965 && this->primaryVarsMeaningBrine_ == rhs.primaryVarsMeaningBrine_
966 && this->primaryVarsMeaningSolvent_ == rhs.primaryVarsMeaningSolvent_
967 && this->pvtRegionIdx_ == rhs.pvtRegionIdx_;
968 }
969
970private:
971 OPM_HOST_DEVICE Implementation& asImp_()
972 { return *static_cast<Implementation*>(this); }
973
974 OPM_HOST_DEVICE const Implementation& asImp_() const
975 { return *static_cast<const Implementation*>(this); }
976
977 OPM_HOST_DEVICE Scalar solventSaturation_() const
978 {
979 if constexpr (enableSolvent) {
980 if (primaryVarsMeaningSolvent() == SolventMeaning::Ss) {
981 return (*this)[Indices::solventSaturationIdx];
982 }
983 }
984 return 0.0;
985 }
986
987 OPM_HOST_DEVICE Scalar zFraction_() const
988 {
989 if constexpr (enableExtbo) {
990 return (*this)[Indices::zFractionIdx];
991 }
992 else {
993 return 0.0;
994 }
995 }
996
997 OPM_HOST_DEVICE Scalar saltConcentration_() const
998 {
999 if constexpr (enableBrine) {
1000 return (*this)[Indices::saltConcentrationIdx];
1001 }
1002 else {
1003 return 0.0;
1004 }
1005 }
1006
1007 Scalar biofilmVolumeFraction_() const
1008 {
1009 if constexpr (enableBioeffects)
1010 return (*this)[Indices::biofilmVolumeFractionIdx];
1011 else
1012 return 0.0;
1013 }
1014
1015 OPM_HOST_DEVICE Scalar temperature_(const Problem& problem, [[maybe_unused]] unsigned globalDofIdx) const
1016 {
1017 if constexpr (enableEnergy) {
1018 return (*this)[Indices::temperatureIdx];
1019 }
1020 else if constexpr (enableTemperature) {
1021 return problem.temperature(globalDofIdx, /*timeIdx*/ 0);
1022 }
1023 else {
1024 return FluidSystem::reservoirTemperature();
1025 }
1026 }
1027
1028 template <class Container>
1029 OPM_HOST_DEVICE void computeCapillaryPressures_(Container& result,
1030 Scalar so,
1031 Scalar sg,
1032 Scalar sw,
1033 const MaterialLawParams& matParams) const
1034 {
1035 using SatOnlyFluidState = SimpleModularFluidState<Scalar,
1036 numPhases,
1037 numComponents,
1038 FluidSystem,
1039 /*storePressure=*/false,
1040 /*storeTemperature=*/false,
1041 /*storeComposition=*/false,
1042 /*storeFugacity=*/false,
1043 /*storeSaturation=*/true,
1044 /*storeDensity=*/false,
1045 /*storeViscosity=*/false,
1046 /*storeEnthalpy=*/false>;
1047 SatOnlyFluidState fluidState;
1048 fluidState.setSaturation(waterPhaseIdx, sw);
1049 fluidState.setSaturation(oilPhaseIdx, so);
1050 fluidState.setSaturation(gasPhaseIdx, sg);
1051
1052 MaterialLaw::capillaryPressures(result, matParams, fluidState);
1053 }
1054
1055 OPM_HOST_DEVICE Scalar pressure_() const
1056 {
1057 return (*this)[Indices::pressureSwitchIdx] * this->getPressureScale();
1058 }
1059
1060 OPM_HOST_DEVICE constexpr Scalar getPressureScale() const
1061 {
1062 // In device code, we do not have access to static members, so we return 1.0
1063 // In most cases, the pressure scale is set to 1.0 anyway, so this is acceptable.
1064 #if OPM_IS_INSIDE_DEVICE_FUNCTION
1065 return Scalar(1.0);
1066 #else
1067 return this->pressureScale_;
1068 #endif
1069 }
1070
1071 void setScaledPressure_(Scalar pressure)
1072 { (*this)[Indices::pressureSwitchIdx] = pressure / (this->getPressureScale()); }
1073
1074 // NOTE: When adding new member variables, be sure to update the template copy constructor,
1075 WaterMeaning primaryVarsMeaningWater_{WaterMeaning::Disabled};
1076 PressureMeaning primaryVarsMeaningPressure_{PressureMeaning::Po};
1077 GasMeaning primaryVarsMeaningGas_{GasMeaning::Disabled};
1078 BrineMeaning primaryVarsMeaningBrine_{BrineMeaning::Disabled};
1079 SolventMeaning primaryVarsMeaningSolvent_{SolventMeaning::Disabled};
1080 unsigned short pvtRegionIdx_;
1081 Scalar pcFactor_;
1082 inline static Scalar pressureScale_ = 1.0;
1083};
1084
1085} // namespace Opm
1086
1087#endif
Contains the classes required to extend the black-oil model by bioeffects.
Contains the classes required to extend the black-oil model by brine.
Contains the classes required to extend the black-oil model by energy.
Contains the classes required to extend the black-oil model by solvent component. For details,...
Declares the properties required by the black oil model.
Contains the classes required to extend the black-oil model by solvents.
Contains the high level supplements required to extend the black oil model by bioeffects.
Definition: blackoilbioeffectsmodules.hh:93
static bool hasPcfactTables()
Definition: blackoilbioeffectsmodules.hh:481
static const TabulatedFunction & pcfactTable(unsigned satnumRegionIdx)
Definition: blackoilbioeffectsmodules.hh:476
Contains the high level supplements required to extend the black oil model by brine.
Definition: blackoilbrinemodules.hh:56
static Scalar saltSol(unsigned regionIdx)
Definition: blackoilbrinemodules.hh:352
static const TabulatedFunction & pcfactTable(unsigned satnumRegionIdx)
Definition: blackoilbrinemodules.hh:296
static bool hasPcfactTables()
Definition: blackoilbrinemodules.hh:342
Contains the high level supplements required to extend the black oil model by energy.
Definition: blackoilenergymodules.hh:60
static void assignPrimaryVars(PrimaryVariables &priVars, const FluidState &fluidState)
Assign the energy specific primary variables to a PrimaryVariables object.
Definition: blackoilenergymodules.hh:265
Contains the high level supplements required to extend the black oil model.
Definition: blackoilextbomodules.hh:62
static Value rs(unsigned pvtRegionIdx, const Value &pressure, const Value &z)
Definition: blackoilextbomodules.hh:348
static Value rv(unsigned pvtRegionIdx, const Value &pressure, const Value &z)
Definition: blackoilextbomodules.hh:352
Represents the primary variables used by the black-oil model.
Definition: blackoilprimaryvariables.hh:72
::Opm::BlackOil::WaterMeaning WaterMeaning
Definition: blackoilprimaryvariables.hh:138
OPM_HOST_DEVICE void setPrimaryVarsMeaningPressure(PressureMeaning newMeaning)
Set the interpretation which should be applied to the switching primary variables.
Definition: blackoilprimaryvariables.hh:281
OPM_HOST_DEVICE void setPrimaryVarsMeaningBrine(BrineMeaning newMeaning)
Set the interpretation which should be applied to the switching primary variables.
Definition: blackoilprimaryvariables.hh:305
static void init()
Definition: blackoilprimaryvariables.hh:192
OPM_HOST_DEVICE BlackOilPrimaryVariables(const BlackOilPrimaryVariables< OtherTypeTag, OtherVectorType > &other)
Assignment from another primary variables object.
Definition: blackoilprimaryvariables.hh:153
::Opm::BlackOil::SolventMeaning SolventMeaning
Definition: blackoilprimaryvariables.hh:142
OPM_HOST_DEVICE void checkDefined() const
< Import base class assignment operators.
Definition: blackoilprimaryvariables.hh:926
OPM_HOST_DEVICE PressureMeaning primaryVarsMeaningPressure() const
Return the interpretation which should be applied to the switching primary variables.
Definition: blackoilprimaryvariables.hh:274
::Opm::BlackOil::GasMeaning GasMeaning
Definition: blackoilprimaryvariables.hh:140
OPM_HOST_DEVICE BlackOilPrimaryVariables()
Definition: blackoilprimaryvariables.hh:165
OPM_HOST_DEVICE bool chopAndNormalizeSaturations()
Definition: blackoilprimaryvariables.hh:871
OPM_HOST_DEVICE unsigned pvtRegionIndex() const
Return the index of the region which should be used for PVT properties.
Definition: blackoilprimaryvariables.hh:253
OPM_HOST_DEVICE bool operator==(const BlackOilPrimaryVariables &rhs) const
Definition: blackoilprimaryvariables.hh:958
void serializeOp(Serializer &serializer)
Definition: blackoilprimaryvariables.hh:946
OPM_HOST_DEVICE void setPrimaryVarsMeaningWater(WaterMeaning newMeaning)
Set the interpretation which should be applied to the switching primary variables.
Definition: blackoilprimaryvariables.hh:267
OPM_HOST_DEVICE void setPrimaryVarsMeaningGas(GasMeaning newMeaning)
Set the interpretation which should be applied to the switching primary variables.
Definition: blackoilprimaryvariables.hh:295
static void registerParameters()
Definition: blackoilprimaryvariables.hh:215
::Opm::BlackOil::BrineMeaning BrineMeaning
Definition: blackoilprimaryvariables.hh:141
BlackOilPrimaryVariables & operator=(const BlackOilPrimaryVariables &other)=default
BlackOilPrimaryVariables(const BlackOilPrimaryVariables &value)=default
Copy constructor.
::Opm::BlackOil::PressureMeaning PressureMeaning
Definition: blackoilprimaryvariables.hh:139
OPM_HOST_DEVICE GasMeaning primaryVarsMeaningGas() const
Return the interpretation which should be applied to the switching primary variables.
Definition: blackoilprimaryvariables.hh:288
OPM_HOST_DEVICE void setPvtRegionIndex(unsigned value)
Set the index of the region which should be used for PVT properties.
Definition: blackoilprimaryvariables.hh:247
bool adaptPrimaryVariables(const Problem &problem, unsigned globalDofIdx, Scalar swMaximum, Scalar thresholdWaterFilledCell, Scalar eps=0.0)
Adapt the interpretation of the switching variables to be physically meaningful.
Definition: blackoilprimaryvariables.hh:493
OPM_HOST_DEVICE void assignNaive(const FluidState &fluidState)
Directly retrieve the primary variables from an arbitrary fluid state.
Definition: blackoilprimaryvariables.hh:322
OPM_HOST_DEVICE BrineMeaning primaryVarsMeaningBrine() const
Definition: blackoilprimaryvariables.hh:298
OPM_HOST_DEVICE void setPrimaryVarsMeaningSolvent(SolventMeaning newMeaning)
Set the interpretation which should be applied to the switching primary variables.
Definition: blackoilprimaryvariables.hh:315
OPM_HOST_DEVICE WaterMeaning primaryVarsMeaningWater() const
Return the interpretation which should be applied to the switching primary variables.
Definition: blackoilprimaryvariables.hh:260
static BlackOilPrimaryVariables serializationTestObject()
Definition: blackoilprimaryvariables.hh:176
OPM_HOST_DEVICE Evaluation makeEvaluation(unsigned varIdx, unsigned timeIdx, LinearizationType linearizationType=LinearizationType()) const
Definition: blackoilprimaryvariables.hh:222
OPM_HOST_DEVICE SolventMeaning primaryVarsMeaningSolvent() const
Definition: blackoilprimaryvariables.hh:308
Contains the high level supplements required to extend the black oil model by solvents.
Definition: blackoilsolventmodules.hh:68
static bool isSolubleInWater()
Definition: blackoilsolventmodules.hh:521
static Value solubilityLimit(unsigned pvtIdx, const Value &temperature, const Value &pressure, const Value &saltConcentration)
Definition: blackoilsolventmodules.hh:503
Represents the primary variables used by the a model.
Definition: fvbaseprimaryvariables.hh:54
BrineMeaning
Definition: blackoilmeanings.hh:42
PressureMeaning
Definition: blackoilmeanings.hh:29
WaterMeaning
Definition: blackoilmeanings.hh:22
SolventMeaning
Definition: blackoilmeanings.hh:48
GasMeaning
Definition: blackoilmeanings.hh:35
SimpleModularFluidState< double, 3, 3, FluidSystemSimple, false, false, false, false, true, false, false, false > SatOnlyFluidState
Definition: EquilibrationHelpers_impl.hpp:53
Definition: blackoilnewtonmethodparams.hpp:31
Definition: blackoilbioeffectsmodules.hh:43
typename Properties::Detail::GetPropImpl< TypeTag, Property >::type::type GetPropType
get the type alias defined in the property (equivalent to old macro GET_PROP_TYPE(....
Definition: propertysystem.hh:233
Definition: linearizationtype.hh:34
Definition: blackoilprimaryvariables.hh:59
static constexpr Scalar value
Definition: blackoilprimaryvariables.hh:59