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
29#include <opm/common/OpmLog/OpmLog.hpp>
30#include <opm/common/utility/gpuDecorators.hpp>
31
32#include <opm/material/common/MathToolbox.hpp>
33#include <opm/material/common/Valgrind.hpp>
34#include <opm/material/fluidsystems/BlackOilFluidSystem.hpp>
35#include <opm/material/fluidstates/SimpleModularFluidState.hpp>
36
40
42
43#include <algorithm>
44#include <array>
45#include <cassert>
46#include <cstddef>
47#include <concepts>
48#include <limits>
49#include <stdexcept>
50#include <type_traits>
51
52#include <fmt/format.h>
53
54namespace Opm::Parameters {
55
56template<class Scalar>
58{ static constexpr Scalar value = 1.0; };
59
60} // namespace Opm::Parameters
61
62namespace Opm::Concepts {
63
64// Identify black-oil phase-switching fluid systems for overload selection.
65template<class T>
66concept BlackOilPhaseSwitchingFluidSystem = requires(const T& fluidSystem) {
67 { fluidSystem.enableDissolvedGas() } -> std::convertible_to<bool>;
68 { fluidSystem.enableDissolvedGasInWater() } -> std::convertible_to<bool>;
69 { fluidSystem.enableVaporizedOil() } -> std::convertible_to<bool>;
70 { fluidSystem.enableVaporizedWater() } -> std::convertible_to<bool>;
71 fluidSystem.oilPvt();
72 fluidSystem.gasPvt();
73 fluidSystem.waterPvt();
74};
75
76} // namespace Opm::Concepts
77
78namespace Opm {
79
85template <class TypeTag, template<class, int> class VectorType = Dune::FieldVector>
86class BlackOilPrimaryVariables : public FvBasePrimaryVariables<TypeTag, VectorType>
87{
90
98
99 // number of equations
100 enum { numEq = getPropValue<TypeTag, Properties::NumEq>() };
101
102 // primary variable indices
103 static constexpr unsigned waterSwitchIdx = Indices::waterSwitchIdx;
104 static constexpr unsigned pressureSwitchIdx = Indices::pressureSwitchIdx;
105 static constexpr unsigned compositionSwitchIdx = Indices::compositionSwitchIdx;
106 static constexpr unsigned saltConcentrationIdx = Indices::saltConcentrationIdx;
107 static constexpr unsigned solventSaturationIdx = Indices::solventSaturationIdx;
108
109 static constexpr bool compositionSwitchEnabled =
110 Indices::compositionSwitchIdx != std::numeric_limits<unsigned>::max();
111 static constexpr bool waterEnabled = Indices::waterEnabled;
112 static constexpr bool gasEnabled = Indices::gasEnabled;
113 static constexpr bool oilEnabled = Indices::oilEnabled;
114
115 // phase indices from the fluid system
116 enum { numPhases = getPropValue<TypeTag, Properties::NumPhases>() };
117 enum { gasPhaseIdx = FluidSystem::gasPhaseIdx };
118 enum { waterPhaseIdx = FluidSystem::waterPhaseIdx };
119 enum { oilPhaseIdx = FluidSystem::oilPhaseIdx };
120
121 // component indices from the fluid system
122 enum { numComponents = getPropValue<TypeTag, Properties::NumComponents>() };
123
124 static constexpr EnergyModules energyModuleType = getPropValue<TypeTag, Properties::EnergyModuleType>();
125
126 static constexpr bool enableBioeffects = getPropValue<TypeTag, Properties::EnableBioeffects>();
127 static constexpr bool enableBrine = getPropValue<TypeTag, Properties::EnableBrine>();
128 static constexpr bool enableExtbo = getPropValue<TypeTag, Properties::EnableExtbo>();
129 static constexpr bool enableFoam = getPropValue<TypeTag, Properties::EnableFoam>();
130 static constexpr bool enableFullyImplicitThermal = energyModuleType == EnergyModules::FullyImplicitThermal;
131 static constexpr bool enablePolymer = getPropValue<TypeTag, Properties::EnablePolymer>();
132 static constexpr bool enableSolvent = getPropValue<TypeTag, Properties::EnableSolvent>();
133
134 enum { enableSaltPrecipitation = getPropValue<TypeTag, Properties::EnableSaltPrecipitation>() };
135 enum { enableVapwat = getPropValue<TypeTag, Properties::EnableVapwat>() };
136 enum { enableMICP = Indices::enableMICP };
137 enum { gasCompIdx = FluidSystem::gasCompIdx };
138 enum { waterCompIdx = FluidSystem::waterCompIdx };
139 enum { oilCompIdx = FluidSystem::oilCompIdx };
140
141 using Toolbox = MathToolbox<Evaluation>;
142 using ComponentVector = Dune::FieldVector<Scalar, numComponents>;
143 using SolventModule = BlackOilSolventModule<TypeTag, enableSolvent>;
144 using ExtboModule = BlackOilExtboModule<TypeTag, enableExtbo>;
146 using BrineModule = BlackOilBrineModule<TypeTag, enableBrine>;
147 using BioeffectsModule = BlackOilBioeffectsModule<TypeTag, enableBioeffects>;
148
149 static_assert(numPhases == 3, "The black-oil model assumes three phases!");
150 static_assert(numComponents == 3, "The black-oil model assumes three components!");
151
152public:
153 // We are instantiating this class with different TypeTags and VectorTypes,
154 // but we still want to be able to copy between them. Therefore, we
155 // need to define the same type aliases in all specializations.
161
162 // Allow conversion between different vector types
163 template<class OtherTypeTag, template<class, int> class OtherVectorType>
165
169 template <class OtherTypeTag, template <class, int> class OtherVectorType>
170 explicit OPM_HOST_DEVICE
172 : ParentType(other)
173 , primaryVarsMeaningWater_(other.primaryVarsMeaningWater_)
174 , primaryVarsMeaningPressure_(other.primaryVarsMeaningPressure_)
175 , primaryVarsMeaningGas_(other.primaryVarsMeaningGas_)
176 , primaryVarsMeaningBrine_(other.primaryVarsMeaningBrine_)
177 , primaryVarsMeaningSolvent_(other.primaryVarsMeaningSolvent_)
178 , pvtRegionIdx_(other.pvtRegionIdx_)
179 , pcFactor_(other.pcFactor_)
180 {
181 }
182
183 OPM_HOST_DEVICE BlackOilPrimaryVariables()
184 {
185 Valgrind::SetUndefined(*this);
186 pvtRegionIdx_ = 0;
187 }
188
193
195 {
197 result.pvtRegionIdx_ = 1;
198 result.primaryVarsMeaningBrine_ = BrineMeaning::Sp;
199 result.primaryVarsMeaningGas_ = GasMeaning::Rv;
200 result.primaryVarsMeaningPressure_ = PressureMeaning::Pg;
201 result.primaryVarsMeaningWater_ = WaterMeaning::Rsw;
202 result.primaryVarsMeaningSolvent_ = SolventMeaning::Ss;
203 for (std::size_t i = 0; i < result.size(); ++i) {
204 result[i] = i + 1;
205 }
206
207 return result;
208 }
209
210 static void init()
211 {
212 // TODO: these parameters have undocumented non-trivial dependencies
213 pressureScale_ = Parameters::Get<Parameters::PressureScale<Scalar>>();
214
215// currently for GPU we do not have a support for the pressureScale_ variable,
216// so we issue a warning if the user has set it to something else than 1.0
217// if we are building with GPU support. Note that we can not only test if we are compiling
218// with a GPU compiler, because we might initialize the parameters from a .cpp compilation unit
219// compiled by a normal C++ compiler.
220#if HAVE_CUDA
221 if (pressureScale_ != Scalar {1.0}) {
222 OpmLog::warning(fmt::format(
223 "Using a pressure scaling different from 1.0 is not supported "
224 "when running with GPU support. We have detected that you are compiling with GPU support, but we can "
225 "not detect whether you are running with GPU support for the assembly or property evaluation. If you "
226 "are doing property evaluation or assembly on the GPU, pressure scaling will be ignored."
227 "Read value of pressure scale: {}",
228 pressureScale_));
229 }
230#endif
231 }
232
233 static void registerParameters()
234 {
235 Parameters::Register<Parameters::PressureScale<Scalar>>
236 ("Scaling of pressure primary variable");
237 }
238
239 OPM_HOST_DEVICE Evaluation
240 makeEvaluation(unsigned varIdx, unsigned timeIdx,
241 LinearizationType linearizationType = LinearizationType()) const
242 {
243 const Scalar scale = varIdx == pressureSwitchIdx ? this->getPressureScale() : Scalar{1.0};
244 if (std::is_same_v<Evaluation, Scalar>) {
245 return (*this)[varIdx] * scale; // finite differences
246 }
247 else {
248 // automatic differentiation
249 if (timeIdx == linearizationType.time) {
250 return Toolbox::createVariable((*this)[varIdx], varIdx) * scale;
251 }
252 else {
253 return Toolbox::createConstant((*this)[varIdx]) * scale;
254 }
255 }
256 }
257
265 OPM_HOST_DEVICE void setPvtRegionIndex(unsigned value)
266 { pvtRegionIdx_ = static_cast<unsigned short>(value); }
267
271 OPM_HOST_DEVICE unsigned pvtRegionIndex() const
272 { return pvtRegionIdx_; }
273
278 OPM_HOST_DEVICE WaterMeaning primaryVarsMeaningWater() const
279 { return primaryVarsMeaningWater_; }
280
285 OPM_HOST_DEVICE void setPrimaryVarsMeaningWater(WaterMeaning newMeaning)
286 { primaryVarsMeaningWater_ = newMeaning; }
287
293 { return primaryVarsMeaningPressure_; }
294
299 OPM_HOST_DEVICE void setPrimaryVarsMeaningPressure(PressureMeaning newMeaning)
300 { primaryVarsMeaningPressure_ = newMeaning; }
301
306 OPM_HOST_DEVICE GasMeaning primaryVarsMeaningGas() const
307 { return primaryVarsMeaningGas_; }
308
313 OPM_HOST_DEVICE void setPrimaryVarsMeaningGas(GasMeaning newMeaning)
314 { primaryVarsMeaningGas_ = newMeaning; }
315
316 OPM_HOST_DEVICE BrineMeaning primaryVarsMeaningBrine() const
317 { return primaryVarsMeaningBrine_; }
318
323 OPM_HOST_DEVICE void setPrimaryVarsMeaningBrine(BrineMeaning newMeaning)
324 { primaryVarsMeaningBrine_ = newMeaning; }
325
327 { return primaryVarsMeaningSolvent_; }
328
333 OPM_HOST_DEVICE void setPrimaryVarsMeaningSolvent(SolventMeaning newMeaning)
334 { primaryVarsMeaningSolvent_ = newMeaning; }
335
339 template <class FluidState>
340 OPM_HOST_DEVICE void assignNaive(const FluidState& fluidState)
341 {
342 using ConstEvaluation = std::remove_reference_t<typename FluidState::ValueType>;
343 using FsEvaluation = std::remove_const_t<ConstEvaluation>;
344 using FsToolbox = MathToolbox<FsEvaluation>;
345
346 const bool gasPresent =
347 fluidState.fluidSystem().phaseIsActive(gasPhaseIdx)
348 ? fluidState.saturation(gasPhaseIdx) > 0.0
349 : false;
350 const bool oilPresent =
351 fluidState.fluidSystem().phaseIsActive(oilPhaseIdx)
352 ? fluidState.saturation(oilPhaseIdx) > 0.0
353 : false;
354 const bool waterPresent =
355 fluidState.fluidSystem().phaseIsActive(waterPhaseIdx)
356 ? fluidState.saturation(waterPhaseIdx) > 0.0
357 : false;
358 const auto& saltSaturation =
359 BlackOil::getSaltSaturation_<FluidSystem, FluidState, Scalar>(fluidState, pvtRegionIdx_);
360 const bool precipitatedSaltPresent = enableSaltPrecipitation ? saltSaturation > 0.0 : false;
361 const bool oneActivePhases = fluidState.fluidSystem().numActivePhases() == 1;
362 // deal with the primary variables for the energy extension
363 if constexpr (enableFullyImplicitThermal) {
364 EnergyModule::assignPrimaryVars(*this, fluidState);
365 }
366
367 // Determine the meaning of the pressure primary variables
368 // Depending on the phases present, this variable is either interpreted as the
369 // pressure of the oil phase, gas phase (if no oil) or water phase (if only water)
370 if (gasPresent && fluidState.fluidSystem().enableVaporizedOil() && !oilPresent) {
371 primaryVarsMeaningPressure_ = PressureMeaning::Pg;
372 }
373 else if (fluidState.fluidSystem().phaseIsActive(oilPhaseIdx)) {
374 primaryVarsMeaningPressure_ = PressureMeaning::Po;
375 }
376 else if (waterPresent && fluidState.fluidSystem().enableDissolvedGasInWater() && !gasPresent) {
377 primaryVarsMeaningPressure_ = PressureMeaning::Pw;
378 }
379 else if (fluidState.fluidSystem().phaseIsActive(gasPhaseIdx)) {
380 primaryVarsMeaningPressure_ = PressureMeaning::Pg;
381 }
382 else {
383 assert(fluidState.fluidSystem().phaseIsActive(waterPhaseIdx));
384 primaryVarsMeaningPressure_ = PressureMeaning::Pw;
385 }
386
387 // Determine the meaning of the water primary variables
388 // Depending on the phases present, this variable is either interpreted as
389 // water saturation or vapporized water in the gas phase
390 // For two-phase gas-oil models and one-phase case the variable is disabled.
391 if (waterPresent && gasPresent) {
392 primaryVarsMeaningWater_ = WaterMeaning::Sw;
393 }
394 else if (gasPresent && fluidState.fluidSystem().enableVaporizedWater()) {
395 primaryVarsMeaningWater_ = WaterMeaning::Rvw;
396 }
397 else if (waterPresent && fluidState.fluidSystem().enableDissolvedGasInWater()) {
398 primaryVarsMeaningWater_ = WaterMeaning::Rsw;
399 }
400 else if (fluidState.fluidSystem().phaseIsActive(waterPhaseIdx) && !oneActivePhases) {
401 primaryVarsMeaningWater_ = WaterMeaning::Sw;
402 }
403 else {
404 primaryVarsMeaningWater_ = WaterMeaning::Disabled;
405 }
406
407 // Determine the meaning of the gas primary variables
408 // Depending on the phases present, this variable is either interpreted as the
409 // saturation of the gas phase, as the fraction of the gas component in the oil
410 // phase (Rs) or as the fraction of the oil component (Rv) in the gas phase.
411 // For two-phase water-oil and water-gas models and one-phase case the variable is disabled.
412 if (gasPresent && oilPresent) {
413 primaryVarsMeaningGas_ = GasMeaning::Sg;
414 }
415 else if (oilPresent && fluidState.fluidSystem().enableDissolvedGas()) {
416 primaryVarsMeaningGas_ = GasMeaning::Rs;
417 }
418 else if (gasPresent && fluidState.fluidSystem().enableVaporizedOil()) {
419 primaryVarsMeaningGas_ = GasMeaning::Rv;
420 }
421 else if (fluidState.fluidSystem().phaseIsActive(gasPhaseIdx) && fluidState.fluidSystem().phaseIsActive(oilPhaseIdx)) {
422 primaryVarsMeaningGas_ = GasMeaning::Sg;
423 }
424 else {
425 primaryVarsMeaningGas_ = GasMeaning::Disabled;
426 }
427
428 // Determine the meaning of the brine primary variables
429 if constexpr (enableSaltPrecipitation) {
430 if (precipitatedSaltPresent) {
431 primaryVarsMeaningBrine_ = BrineMeaning::Sp;
432 }
433 else {
434 primaryVarsMeaningBrine_ = BrineMeaning::Cs;
435 }
436 }
437 else {
438 primaryVarsMeaningBrine_ = BrineMeaning::Disabled;
439 }
440
441 // assign the actual primary variables
442 switch (primaryVarsMeaningPressure()) {
443 case PressureMeaning::Po:
444 this->setScaledPressure_(FsToolbox::value(fluidState.pressure(oilPhaseIdx)));
445 break;
446 case PressureMeaning::Pg:
447 this->setScaledPressure_(FsToolbox::value(fluidState.pressure(gasPhaseIdx)));
448 break;
449 case PressureMeaning::Pw:
450 this->setScaledPressure_(FsToolbox::value(fluidState.pressure(waterPhaseIdx)));
451 break;
452 default:
453 OPM_THROW(std::logic_error, "No valid primary variable selected for pressure");
454 }
455
456 switch (primaryVarsMeaningWater()) {
457 case WaterMeaning::Sw:
458 {
459 (*this)[waterSwitchIdx] = FsToolbox::value(fluidState.saturation(waterPhaseIdx));
460 break;
461 }
462 case WaterMeaning::Rvw:
463 {
464 const auto& rvw = BlackOil::getRvw_<FluidSystem, FluidState, Scalar>(fluidState, pvtRegionIdx_);
465 (*this)[waterSwitchIdx] = rvw;
466 break;
467 }
468 case WaterMeaning::Rsw:
469 {
470 const auto& Rsw = BlackOil::getRsw_<FluidSystem, FluidState, Scalar>(fluidState, pvtRegionIdx_);
471 (*this)[waterSwitchIdx] = Rsw;
472 break;
473 }
475 break;
476 default:
477 OPM_THROW(std::logic_error, "No valid primary variable selected for water");
478 }
479 switch (primaryVarsMeaningGas()) {
480 case GasMeaning::Sg:
481 (*this)[compositionSwitchIdx] = FsToolbox::value(fluidState.saturation(gasPhaseIdx));
482 break;
483 case GasMeaning::Rs:
484 {
485 const auto& rs = BlackOil::getRs_<FluidSystem, FluidState, Scalar>(fluidState, pvtRegionIdx_);
486 (*this)[compositionSwitchIdx] = rs;
487 break;
488 }
489 case GasMeaning::Rv:
490 {
491 const auto& rv = BlackOil::getRv_<FluidSystem, FluidState, Scalar>(fluidState, pvtRegionIdx_);
492 (*this)[compositionSwitchIdx] = rv;
493 break;
494 }
496 break;
497 default:
498 OPM_THROW(std::logic_error, "No valid primary variable selected for composision");
499 }
500 }
501
513 bool adaptPrimaryVariables(const Problem& problem,
514 unsigned globalDofIdx,
515 Scalar swMaximum,
516 Scalar thresholdWaterFilledCell, Scalar eps = 0.0)
517 {
518 return adaptPrimaryVariables(problem, FluidSystem{}, globalDofIdx,
519 swMaximum, thresholdWaterFilledCell, eps);
520 }
521
522 template<Concepts::BlackOilPhaseSwitchingFluidSystem FluidSystemInstance>
523 OPM_HOST_DEVICE bool adaptPrimaryVariables(const Problem& problem,
524 const FluidSystemInstance& fluidSystem,
525 unsigned globalDofIdx,
526 [[maybe_unused]] Scalar swMaximum,
527 Scalar thresholdWaterFilledCell, Scalar eps = 0.0)
528 {
529 // this function accesses quite a few black-oil specific low-level functions
530 // directly for better performance (instead of going the canonical way through
531 // the IntensiveQuantities). The reason is that most intensive quantities are not
532 // required to be able to decide if the primary variables needs to be switched or
533 // not, so it would be a waste to compute them.
534
535 // Both the primary variable meaning of water and gas are disabled i.e.
536 // It is a one-phase case and we no variable meaning switch is needed.
539 {
540 return false;
541 }
542
543 // Read the current saturation from the primary variables
544 Scalar sw = 0.0;
545 Scalar sg = 0.0;
546 Scalar saltConcentration = 0.0;
547 const Scalar& T = asImp_().temperature_(problem, globalDofIdx, fluidSystem);
549 sw = (*this)[waterSwitchIdx];
550 }
552 sg = (*this)[compositionSwitchIdx];
553 }
554 if (primaryVarsMeaningWater() == WaterMeaning::Rsw) {
555 sw = 1.0;
556 }
557
558 if (primaryVarsMeaningGas() == GasMeaning::Disabled && gasEnabled) {
559 sg = 1.0 - sw; // water + gas case
560 }
561
562 // if solid phase disappeares: Sp (Solid salt saturation) -> Cs (salt concentration)
563 // if solid phase appears: Cs (salt concentration) -> Sp (Solid salt saturation)
564 if constexpr (enableSaltPrecipitation) {
565 const Scalar saltSolubility = BrineModule::saltSol(pvtRegionIndex());
566 if (primaryVarsMeaningBrine() == BrineMeaning::Sp) {
567 saltConcentration = saltSolubility;
568 const Scalar saltSat = (*this)[saltConcentrationIdx];
569 if (saltSat < -eps) { // precipitated salt dissappears
570 setPrimaryVarsMeaningBrine(BrineMeaning::Cs);
571 (*this)[saltConcentrationIdx] = saltSolubility; // set salt concentration to solubility limit
572 }
573 }
574 else if (primaryVarsMeaningBrine() == BrineMeaning::Cs) {
575 saltConcentration = (*this)[saltConcentrationIdx];
576 if (saltConcentration > saltSolubility + eps) { // salt concentration exceeds solubility limit
577 setPrimaryVarsMeaningBrine(BrineMeaning::Sp);
578 (*this)[saltConcentrationIdx] = 0.0;
579 }
580 }
581 }
582
583 // if solvent saturation disappeares: Ss (Solvent saturation) -> Rsolw (solvent dissolved in water)
584 // if solvent saturation appears: Rsolw (solvent dissolved in water) -> Ss (Solvent saturation)
585 // Scalar rsolw = 0.0; // not needed at the moment since we dont allow for vapwat in combination with rsolw
586 if constexpr (enableSolvent) {
587 if (SolventModule::isSolubleInWater()) {
588 const Scalar p = (*this)[pressureSwitchIdx]; // cap-pressure?
589 const Scalar solLimit =
590 SolventModule::solubilityLimit(pvtRegionIndex(), T , p, saltConcentration);
591 if (primaryVarsMeaningSolvent() == SolventMeaning::Ss) {
592 const Scalar solSat = (*this)[solventSaturationIdx];
593 if (solSat < -eps) { // solvent dissappears
594 setPrimaryVarsMeaningSolvent(SolventMeaning::Rsolw);
595 (*this)[solventSaturationIdx] = solLimit; // set rsolw to solubility limit
596 }
597 }
598 else if (primaryVarsMeaningSolvent() == SolventMeaning::Rsolw) {
599 const Scalar rsolw = (*this)[solventSaturationIdx];
600 if (rsolw > solLimit + eps) { // solvent appears as phase
601 setPrimaryVarsMeaningSolvent(SolventMeaning::Ss);
602 (*this)[solventSaturationIdx] = 0.0;
603 }
604 }
605 }
606 }
607
608 // keep track if any meaning has changed
609 bool changed = false;
610
611 // Special case for cells with almost only water
612 // for these cells both saturations (if the phase is enabled) is used
613 // to avoid singular systems.
614 // If dissolved gas in water is enabled we shouldn't enter
615 // here but instead switch to Rsw as primary variable
616 // as sw >= 1.0 -> gas <= 0 (i.e. gas phase disappears)
617 if (sw >= thresholdWaterFilledCell && !fluidSystem.enableDissolvedGasInWater()) {
618 // make sure water saturations does not exceed sw_maximum. Default to 1.0
619 if constexpr (waterEnabled) {
620 (*this)[Indices::waterSwitchIdx] = std::min(swMaximum, sw);
622 }
623 // the hydrocarbon gas saturation is set to 0.0
624 if constexpr (compositionSwitchEnabled) {
625 (*this)[Indices::compositionSwitchIdx] = 0.0;
626 }
627
629 if (changed) {
630 if constexpr (compositionSwitchEnabled) {
632 }
633
634 // use water pressure?
635 }
636 return changed;
637 }
638
639 pcFactor_ = 1.0;
640 if constexpr (enableBrine) {
641 if (BrineModule::hasPcfactTables() && primaryVarsMeaningBrine() == BrineMeaning::Sp) {
642 unsigned satnumRegionIdx = problem.satnumRegionIndex(globalDofIdx);
643 Scalar Sp = saltConcentration_();
644 Scalar porosityFactor = std::min(1.0 - Sp, 1.0); //phi/phi_0
645 const auto& pcfactTable = BrineModule::pcfactTable(satnumRegionIdx);
646 pcFactor_ = pcfactTable.eval(porosityFactor, /*extrapolation=*/true);
647 }
648 }
649 else if constexpr (enableBioeffects) {
650 if (BioeffectsModule::hasPcfactTables() && problem.referencePorosity(globalDofIdx, 0) > 0) {
651 unsigned satnumRegionIdx = problem.satnumRegionIndex(globalDofIdx);
652 Scalar Sb = biofilmVolumeFraction_() /
653 problem.referencePorosity(globalDofIdx, 0);
654 Scalar porosityFactor = std::min(1.0 - Sb, 1.0); //phi/phi_0
655 const auto& pcfactTable = BioeffectsModule::pcfactTable(satnumRegionIdx);
656 pcFactor_ = pcfactTable.eval(porosityFactor, /*extrapolation=*/true);
657 }
658 }
659
660 switch (primaryVarsMeaningWater()) {
661 case WaterMeaning::Sw:
662 {
663 // if water phase disappeares: Sw (water saturation) -> Rvw (fraction of water in gas phase)
664 if (sw < -eps && sg > eps && fluidSystem.enableVaporizedWater()) {
665 Scalar p = this->pressure_();
666 if (primaryVarsMeaningPressure() == PressureMeaning::Po) {
667 std::array<Scalar, numPhases> pC{};
668 const MaterialLawParams& matParams = problem.materialLawParams(globalDofIdx);
669 const Scalar so = 1.0 - sg - solventSaturation_();
670 computeCapillaryPressures_(pC, so, sg + solventSaturation_(), /*sw=*/ 0.0, matParams);
671 p += pcFactor_ * (pC[gasPhaseIdx] - pC[oilPhaseIdx]);
672 }
673 const Scalar rvwSat =
674 fluidSystem.gasPvt().saturatedWaterVaporizationFactor(pvtRegionIdx_,
675 T,
676 p,
677 saltConcentration);
678 setPrimaryVarsMeaningWater(WaterMeaning::Rvw);
679 (*this)[Indices::waterSwitchIdx] = rvwSat; // primary variable becomes Rvw
680 changed = true;
681 break;
682 }
683 // if gas phase disappeares: Sw (water saturation) -> Rsw (fraction of gas in water phase)
684 // and Pg (gas pressure) -> Pw ( water pressure)
685 if (sg < -eps && sw > eps && fluidSystem.enableDissolvedGasInWater()) {
686 const Scalar pg = this->pressure_();
687 assert(primaryVarsMeaningPressure() == PressureMeaning::Pg);
688 std::array<Scalar, numPhases> pC = { 0.0 };
689 const MaterialLawParams& matParams = problem.materialLawParams(globalDofIdx);
690 const Scalar so = 1.0 - sw - solventSaturation_();
691 computeCapillaryPressures_(pC, so, /*sg=*/ 0.0, sw, matParams);
692 const Scalar pw = pg + pcFactor_ * (pC[waterPhaseIdx] - pC[gasPhaseIdx]);
693 const Scalar rswSat =
694 fluidSystem.waterPvt().saturatedGasDissolutionFactor(pvtRegionIdx_,
695 T,
696 pw,
697 saltConcentration);
698 setPrimaryVarsMeaningWater(WaterMeaning::Rsw);
699 const Scalar rswMax = problem.maxGasDissolutionFactor(/*timeIdx=*/0, globalDofIdx);
700 (*this)[Indices::waterSwitchIdx] = std::min(rswSat, rswMax); //primary variable becomes Rsw
701 setPrimaryVarsMeaningPressure(PressureMeaning::Pw);
702 this->setScaledPressure_(pw);
703 changed = true;
704 break;
705 }
706 break;
707 }
708 case WaterMeaning::Rvw:
709 {
710 const Scalar& rvw = (*this)[waterSwitchIdx];
711 Scalar p = this->pressure_();
712 if (primaryVarsMeaningPressure() == PressureMeaning::Po) {
713 std::array<Scalar, numPhases> pC{};
714 const MaterialLawParams& matParams = problem.materialLawParams(globalDofIdx);
715 const Scalar so = 1.0 - sg - solventSaturation_();
716 computeCapillaryPressures_(pC, so, sg + solventSaturation_(), /*sw=*/ 0.0, matParams);
717 p += pcFactor_ * (pC[gasPhaseIdx] - pC[oilPhaseIdx]);
718 }
719 const Scalar rvwSat =
720 fluidSystem.gasPvt().saturatedWaterVaporizationFactor(pvtRegionIdx_,
721 T,
722 p,
723 saltConcentration);
724 // if water phase appears: Rvw (fraction of water in gas phase) -> Sw (water saturation)
725 if (rvw > rvwSat * (1.0 + eps)) {
727 (*this)[Indices::waterSwitchIdx] = 0.0; // water saturation
728 changed = true;
729 }
730 break;
731 }
732 case WaterMeaning::Rsw:
733 {
734 // Gas phase not present. The hydrocarbon gas phase
735 // appears as soon as more of the gas component is present in the water phase
736 // than what saturated water can hold.
737 const Scalar& pw = this->pressure_();
738 assert(primaryVarsMeaningPressure() == PressureMeaning::Pw);
739 const Scalar rswSat =
740 fluidSystem.waterPvt().saturatedGasDissolutionFactor(pvtRegionIdx_,
741 T,
742 pw,
743 saltConcentration);
744
745 const Scalar rsw = (*this)[Indices::waterSwitchIdx];
746 const Scalar rswMax = problem.maxGasDissolutionFactor(/*timeIdx=*/0, globalDofIdx);
747 if (rsw > std::min(rswSat, rswMax)) {
748 // the gas phase appears, i.e., switch the primary variables to WaterMeaning::Sw
750 (*this)[Indices::waterSwitchIdx] = 1.0; // hydrocarbon water saturation
751 setPrimaryVarsMeaningPressure(PressureMeaning::Pg);
752 std::array<Scalar, numPhases> pC{};
753 const MaterialLawParams& matParams = problem.materialLawParams(globalDofIdx);
754 computeCapillaryPressures_(pC, /*so=*/ 0.0, /*sg=*/ 0.0, /*sw=*/ 1.0, matParams);
755 const Scalar pg = pw + pcFactor_ * (pC[gasPhaseIdx] - pC[waterPhaseIdx]);
756 this->setScaledPressure_(pg);
757 changed = true;
758 }
759 break;
760 }
762 break;
763 default:
764 OPM_THROW(std::logic_error, "No valid primary variable selected for water");
765 }
766
767 // if gas phase disappeares: Sg (gas saturation) -> Rs (fraction of gas in oil phase)
768 // if oil phase disappeares: Sg (gas saturation) -> Rv (fraction of oil in gas phase)
769 // Po (oil pressure ) -> Pg (gas pressure)
770
771 // if gas phase appears: Rs (fraction of gas in oil phase) -> Sg (gas saturation)
772 // if oil phase appears: Rv (fraction of oil in gas phase) -> Sg (gas saturation)
773 // Pg (gas pressure ) -> Po (oil pressure)
774 if constexpr (compositionSwitchEnabled) {
775 switch (primaryVarsMeaningGas()) {
776 case GasMeaning::Sg:
777 {
778 const Scalar s = 1.0 - sw - solventSaturation_();
779 if (sg < -eps && s > 0.0 && fluidSystem.enableDissolvedGas()) {
780 const Scalar po = this->pressure_();
782 const Scalar soMax = std::max(s, problem.maxOilSaturation(globalDofIdx));
783 const Scalar rsMax = problem.maxGasDissolutionFactor(/*timeIdx=*/0, globalDofIdx);
784 Scalar rsSat;
785 if constexpr (enableExtbo) {
786 rsSat = ExtboModule::rs(pvtRegionIndex(), po, zFraction_());
787 }
788 else {
789 rsSat = fluidSystem.oilPvt().saturatedGasDissolutionFactor(pvtRegionIdx_,
790 T,
791 po,
792 s,
793 soMax);
794 }
795 Scalar rs = std::min(rsMax, rsSat);
796 if constexpr (!enableExtbo) {
797 const Scalar so = s - sg;
798 if (so < maxOilSaturationForComponentRs_) {
799 rs = gasOilRatioOfPresentComponents_(problem, globalDofIdx, T, po, so, sg, rs, fluidSystem);
800 }
801 }
802 (*this)[Indices::compositionSwitchIdx] = rs;
803 changed = true;
804
805 }
806 const Scalar so = 1.0 - sw - solventSaturation_() - sg;
807 if (so < -eps && sg > 0.0 && fluidSystem.enableVaporizedOil()) {
808 // the oil phase disappeared and some hydrocarbon gas phase is still
809 // present, i.e., switch the primary variables to GasMeaning::Rv.
810 // we only have the oil pressure readily available, but we need the gas
811 // pressure, i.e. we must determine capillary pressure
812 const Scalar po = this->pressure_();
813 std::array<Scalar, numPhases> pC{};
814 const MaterialLawParams& matParams = problem.materialLawParams(globalDofIdx);
815 computeCapillaryPressures_(pC, /*so=*/0.0, sg + solventSaturation_(), sw, matParams);
816 const Scalar pg = po + pcFactor_ * (pC[gasPhaseIdx] - pC[oilPhaseIdx]);
817
818 // we start at the GasMeaning::Rv value that corresponds to that of oil-saturated
819 // hydrocarbon gas
820 setPrimaryVarsMeaningPressure(PressureMeaning::Pg);
821 this->setScaledPressure_(pg);
822 const Scalar soMax = problem.maxOilSaturation(globalDofIdx);
823 const Scalar rvMax = problem.maxOilVaporizationFactor(/*timeIdx=*/0, globalDofIdx);
824 Scalar rvSat;
825 if constexpr (enableExtbo) {
826 rvSat = ExtboModule::rv(pvtRegionIndex(), pg, zFraction_());
827 }
828 else {
829 rvSat = fluidSystem.gasPvt().saturatedOilVaporizationFactor(pvtRegionIdx_,
830 T,
831 pg,
832 Scalar(0),
833 soMax);
834 }
836 (*this)[Indices::compositionSwitchIdx] = std::min(rvMax, rvSat);
837 changed = true;
838 }
839 break;
840 }
841 case GasMeaning::Rs:
842 {
843 // Gas phase not present. The hydrocarbon gas phase
844 // appears as soon as more of the gas component is present in the oil phase
845 // than what saturated oil can hold.
846 const Scalar po = this->pressure_();
847 const Scalar so = 1.0 - sw - solventSaturation_();
848 const Scalar soMax = std::max(so, problem.maxOilSaturation(globalDofIdx));
849 const Scalar rsMax = problem.maxGasDissolutionFactor(/*timeIdx=*/0, globalDofIdx);
850 Scalar rsSat;
851 if constexpr (enableExtbo) {
852 rsSat = ExtboModule::rs(pvtRegionIndex(), po, zFraction_());
853 }
854 else {
855 rsSat = fluidSystem.oilPvt().saturatedGasDissolutionFactor(pvtRegionIdx_,
856 T,
857 po,
858 so,
859 soMax);
860 }
861 const Scalar rs = (*this)[Indices::compositionSwitchIdx];
862 if (rs > std::min(rsMax, rsSat * (Scalar{1.0} + eps))) {
863 // the gas phase appears, i.e., switch the primary variables to GasMeaning::Sg
865 (*this)[Indices::compositionSwitchIdx] = 0.0; // hydrocarbon gas saturation
866 changed = true;
867 }
868 break;
869 }
870 case GasMeaning::Rv:
871 {
872 // The oil phase appears as
873 // soon as more of the oil component is present in the hydrocarbon gas phase
874 // than what saturated gas contains. Note that we use the blackoil specific
875 // low-level PVT objects here for performance reasons.
876 const Scalar pg = this->pressure_();
877 const Scalar soMax = problem.maxOilSaturation(globalDofIdx);
878 const Scalar rvMax = problem.maxOilVaporizationFactor(/*timeIdx=*/0, globalDofIdx);
879 Scalar rvSat;
880 if constexpr (enableExtbo) {
881 rvSat = ExtboModule::rv(pvtRegionIndex(), pg, zFraction_());
882 }
883 else {
884 rvSat = fluidSystem.gasPvt().saturatedOilVaporizationFactor(pvtRegionIdx_,
885 T,
886 pg,
887 /*so=*/Scalar(0.0),
888 soMax);
889 }
890 const Scalar rv = (*this)[Indices::compositionSwitchIdx];
891 if (rv > std::min(rvMax, rvSat * (Scalar{1.0} + eps))) {
892 // switch to phase equilibrium mode because the oil phase appears. here
893 // we also need the capillary pressures to calculate the oil phase
894 // pressure using the gas phase pressure
895 const Scalar sg2 = 1.0 - sw - solventSaturation_();
896 std::array<Scalar, numPhases> pC{};
897 const MaterialLawParams& matParams = problem.materialLawParams(globalDofIdx);
898 computeCapillaryPressures_(pC,
899 /*so=*/0.0,
900 /*sg=*/sg2 + solventSaturation_(),
901 sw,
902 matParams);
903 const Scalar po = pg + pcFactor_ * (pC[oilPhaseIdx] - pC[gasPhaseIdx]);
904
906 setPrimaryVarsMeaningPressure(PressureMeaning::Po);
907 this->setScaledPressure_(po);
908 (*this)[Indices::compositionSwitchIdx] = sg2; // hydrocarbon gas saturation
909 changed = true;
910 }
911 break;
912 }
914 break;
915 default:
916 OPM_THROW(std::logic_error, "No valid primary variable selected for gas");
917 }
918 }
919 return changed;
920 }
921
922 OPM_HOST_DEVICE bool chopAndNormalizeSaturations()
923 {
926 {
927 return false;
928 }
929 Scalar sw = 0.0;
931 sw = (*this)[Indices::waterSwitchIdx];
932 }
933 Scalar sg = 0.0;
935 sg = (*this)[Indices::compositionSwitchIdx];
936 }
937
938 Scalar ssol = 0.0;
939 if (primaryVarsMeaningSolvent() == SolventMeaning::Ss) {
940 ssol =(*this) [Indices::solventSaturationIdx];
941 }
942
943 Scalar so = 1.0 - sw - sg - ssol;
944 sw = std::min(std::max(sw, Scalar{0.0}), Scalar{1.0});
945 so = std::min(std::max(so, Scalar{0.0}), Scalar{1.0});
946 sg = std::min(std::max(sg, Scalar{0.0}), Scalar{1.0});
947 ssol = std::min(std::max(ssol, Scalar{0.0}), Scalar{1.0});
948 const Scalar st = sw + so + sg + ssol;
949 sw = sw / st;
950 sg = sg / st;
951 ssol = ssol / st;
952 assert(st > 0.5);
954 (*this)[Indices::waterSwitchIdx] = sw;
955 }
957 (*this)[Indices::compositionSwitchIdx] = sg;
958 }
959 if (primaryVarsMeaningSolvent() == SolventMeaning::Ss) {
960 (*this) [Indices::solventSaturationIdx] = ssol;
961 }
962
963 return (st != 1);
964 }
965
967
968 using ParentType::operator=;
969
977 OPM_HOST_DEVICE void checkDefined() const
978 {
979#ifndef NDEBUG
980 // check the "real" primary variables
981 for (unsigned i = 0; i < this->size(); ++i) {
982 Valgrind::CheckDefined((*this)[i]);
983 }
984
985 // check the "pseudo" primary variables
986 Valgrind::CheckDefined(primaryVarsMeaningWater_);
987 Valgrind::CheckDefined(primaryVarsMeaningGas_);
988 Valgrind::CheckDefined(primaryVarsMeaningPressure_);
989 Valgrind::CheckDefined(primaryVarsMeaningBrine_);
990 Valgrind::CheckDefined(primaryVarsMeaningSolvent_);
991
992 Valgrind::CheckDefined(pvtRegionIdx_);
993#endif // NDEBUG
994 }
995
996 template<class Serializer>
997 void serializeOp(Serializer& serializer)
998 {
999 using FV = Dune::FieldVector<Scalar, getPropValue<TypeTag, Properties::NumEq>()>;
1000 serializer(static_cast<FV&>(*this));
1001 serializer(primaryVarsMeaningWater_);
1002 serializer(primaryVarsMeaningPressure_);
1003 serializer(primaryVarsMeaningGas_);
1004 serializer(primaryVarsMeaningBrine_);
1005 serializer(primaryVarsMeaningSolvent_);
1006 serializer(pvtRegionIdx_);
1007 }
1008
1009 OPM_HOST_DEVICE bool operator==(const BlackOilPrimaryVariables& rhs) const
1010 {
1011 return
1012 static_cast<const FvBasePrimaryVariables<TypeTag>&>(*this) == rhs
1013 && this->primaryVarsMeaningWater_ == rhs.primaryVarsMeaningWater_
1014 && this->primaryVarsMeaningPressure_ == rhs.primaryVarsMeaningPressure_
1015 && this->primaryVarsMeaningGas_ == rhs.primaryVarsMeaningGas_
1016 && this->primaryVarsMeaningBrine_ == rhs.primaryVarsMeaningBrine_
1017 && this->primaryVarsMeaningSolvent_ == rhs.primaryVarsMeaningSolvent_
1018 && this->pvtRegionIdx_ == rhs.pvtRegionIdx_;
1019 }
1020
1021private:
1022 OPM_HOST_DEVICE Implementation& asImp_()
1023 { return *static_cast<Implementation*>(this); }
1024
1025 OPM_HOST_DEVICE const Implementation& asImp_() const
1026 { return *static_cast<const Implementation*>(this); }
1027
1028 OPM_HOST_DEVICE Scalar solventSaturation_() const
1029 {
1030 if constexpr (enableSolvent) {
1031 if (primaryVarsMeaningSolvent() == SolventMeaning::Ss) {
1032 return (*this)[Indices::solventSaturationIdx];
1033 }
1034 }
1035 return 0.0;
1036 }
1037
1038 OPM_HOST_DEVICE Scalar zFraction_() const
1039 {
1040 if constexpr (enableExtbo) {
1041 return (*this)[Indices::zFractionIdx];
1042 }
1043 else {
1044 return 0.0;
1045 }
1046 }
1047
1048 OPM_HOST_DEVICE Scalar saltConcentration_() const
1049 {
1050 if constexpr (enableBrine) {
1051 return (*this)[Indices::saltConcentrationIdx];
1052 }
1053 else {
1054 return 0.0;
1055 }
1056 }
1057
1058 Scalar biofilmVolumeFraction_() const
1059 {
1060 if constexpr (enableBioeffects)
1061 return (*this)[Indices::biofilmVolumeFractionIdx];
1062 else
1063 return 0.0;
1064 }
1065
1066 template<class FluidSystemInstance = FluidSystem>
1067 OPM_HOST_DEVICE Scalar temperature_(const Problem& problem,
1068 [[maybe_unused]] unsigned globalDofIdx,
1069 [[maybe_unused]] const FluidSystemInstance& fluidSystem = FluidSystem{}) const
1070 {
1071 if constexpr (energyModuleType == EnergyModules::FullyImplicitThermal) {
1072 return (*this)[Indices::temperatureIdx];
1073 }
1074 else if (energyModuleType == EnergyModules::NoTemperature) {
1075 return fluidSystem.reservoirTemperature(pvtRegionIdx_);
1076 } else {
1077 return problem.temperature(globalDofIdx, /*timeIdx*/ 0);
1078 }
1079 }
1080
1081 template <class Container>
1082 OPM_HOST_DEVICE void computeCapillaryPressures_(Container& result,
1083 Scalar so,
1084 Scalar sg,
1085 Scalar sw,
1086 const MaterialLawParams& matParams) const
1087 {
1088 using SatOnlyFluidState = SimpleModularFluidState<Scalar,
1089 numPhases,
1090 numComponents,
1091 FluidSystem,
1092 /*storePressure=*/false,
1093 /*storeTemperature=*/false,
1094 /*storeComposition=*/false,
1095 /*storeFugacity=*/false,
1096 /*storeSaturation=*/true,
1097 /*storeDensity=*/false,
1098 /*storeViscosity=*/false,
1099 /*storeEnthalpy=*/false>;
1100 SatOnlyFluidState fluidState;
1101 fluidState.setSaturation(waterPhaseIdx, sw);
1102 fluidState.setSaturation(oilPhaseIdx, so);
1103 fluidState.setSaturation(gasPhaseIdx, sg);
1104
1105 MaterialLaw::capillaryPressures(result, matParams, fluidState);
1106 }
1107
1138 template<class FluidSystemInstance>
1139 OPM_HOST_DEVICE Scalar gasOilRatioOfPresentComponents_(const Problem& problem,
1140 unsigned globalDofIdx,
1141 Scalar T,
1142 Scalar po,
1143 Scalar so,
1144 Scalar sg,
1145 Scalar rsSwitch,
1146 const FluidSystemInstance& fluidSystem) const
1147 {
1148 const Scalar soMax = std::max(so, static_cast<Scalar>(problem.maxOilSaturation(globalDofIdx)));
1149
1150 const Scalar rsMax = problem.maxGasDissolutionFactor(/*timeIdx=*/0, globalDofIdx);
1151 const Scalar rsSat = fluidSystem.oilPvt().saturatedGasDissolutionFactor(pvtRegionIdx_, T, po,
1152 so, soMax);
1153 const Scalar rs = std::min(rsMax, rsSat);
1154
1155 Scalar rv = 0.0;
1156 if (fluidSystem.enableVaporizedOil()) {
1157 const Scalar rvMax = problem.maxOilVaporizationFactor(/*timeIdx=*/0, globalDofIdx);
1158 const Scalar rvSat = fluidSystem.gasPvt().saturatedOilVaporizationFactor(pvtRegionIdx_, T, po,
1159 so, soMax);
1160 rv = std::min(rvMax, rvSat);
1161 }
1162
1163 const Scalar bo = fluidSystem.oilPvt().inverseFormationVolumeFactor(pvtRegionIdx_, T, po, rs);
1164 const Scalar bg = fluidSystem.gasPvt().inverseFormationVolumeFactor(pvtRegionIdx_, T, po, rv,
1165 /*Rvw=*/Scalar{0.0});
1166 const Scalar gasComponent = rs * bo * so + bg * sg;
1167 const Scalar oilComponent = bo * so + rv * bg * sg;
1168 if (!(oilComponent > 0.0)) {
1169 return rsSwitch;
1170 }
1171 return std::clamp(gasComponent / oilComponent, Scalar{0.0}, rsSwitch);
1172 }
1173
1174 OPM_HOST_DEVICE Scalar pressure_() const
1175 {
1176 return (*this)[Indices::pressureSwitchIdx] * this->getPressureScale();
1177 }
1178
1179 OPM_HOST_DEVICE constexpr Scalar getPressureScale() const
1180 {
1181 // In device code, we do not have access to static members, so we return 1.0
1182 // In most cases, the pressure scale is set to 1.0 anyway, so this is acceptable.
1183 #if OPM_IS_INSIDE_DEVICE_FUNCTION
1184 return Scalar(1.0);
1185 #else
1186 return this->pressureScale_;
1187 #endif
1188 }
1189
1190 OPM_HOST_DEVICE void setScaledPressure_(Scalar pressure)
1191 { (*this)[Indices::pressureSwitchIdx] = pressure / (this->getPressureScale()); }
1192
1193 // NOTE: When adding new member variables, be sure to update the template copy constructor,
1194 WaterMeaning primaryVarsMeaningWater_{WaterMeaning::Disabled};
1195 PressureMeaning primaryVarsMeaningPressure_{PressureMeaning::Po};
1196 GasMeaning primaryVarsMeaningGas_{GasMeaning::Disabled};
1197 BrineMeaning primaryVarsMeaningBrine_{BrineMeaning::Disabled};
1198 SolventMeaning primaryVarsMeaningSolvent_{SolventMeaning::Disabled};
1199 unsigned short pvtRegionIdx_{};
1200 Scalar pcFactor_{};
1201 inline static Scalar pressureScale_ = 1.0;
1202
1203 // Oil saturation below which gasOilRatioOfPresentComponents_() is used
1204 // to initialise Rs when the gas phase disappears. Not sensitive: in a
1205 // field case with oil entering water-filled cells and in the regression
1206 // tests, values from 0.05 to 0.3 performed equally. Below about 0.05
1207 // the field case had linear solver failures again.
1208 static constexpr Scalar maxOilSaturationForComponentRs_ = 0.1;
1209};
1210
1211} // namespace Opm
1212
1213#endif
Contains classes extending the black-oil model. \detail This file holds dummy definitions,...
Declares the properties required by the black oil model.
Definition: blackoilmodules.hpp:63
Represents the primary variables used by the black-oil model.
Definition: blackoilprimaryvariables.hh:87
::Opm::BlackOil::WaterMeaning WaterMeaning
Definition: blackoilprimaryvariables.hh:156
OPM_HOST_DEVICE void setPrimaryVarsMeaningPressure(PressureMeaning newMeaning)
Set the interpretation which should be applied to the switching primary variables.
Definition: blackoilprimaryvariables.hh:299
OPM_HOST_DEVICE void setPrimaryVarsMeaningBrine(BrineMeaning newMeaning)
Set the interpretation which should be applied to the switching primary variables.
Definition: blackoilprimaryvariables.hh:323
static void init()
Definition: blackoilprimaryvariables.hh:210
OPM_HOST_DEVICE BlackOilPrimaryVariables(const BlackOilPrimaryVariables< OtherTypeTag, OtherVectorType > &other)
Assignment from another primary variables object.
Definition: blackoilprimaryvariables.hh:171
::Opm::BlackOil::SolventMeaning SolventMeaning
Definition: blackoilprimaryvariables.hh:160
OPM_HOST_DEVICE bool adaptPrimaryVariables(const Problem &problem, const FluidSystemInstance &fluidSystem, unsigned globalDofIdx, Scalar swMaximum, Scalar thresholdWaterFilledCell, Scalar eps=0.0)
Definition: blackoilprimaryvariables.hh:523
OPM_HOST_DEVICE void checkDefined() const
< Import base class assignment operators.
Definition: blackoilprimaryvariables.hh:977
OPM_HOST_DEVICE PressureMeaning primaryVarsMeaningPressure() const
Return the interpretation which should be applied to the switching primary variables.
Definition: blackoilprimaryvariables.hh:292
::Opm::BlackOil::GasMeaning GasMeaning
Definition: blackoilprimaryvariables.hh:158
OPM_HOST_DEVICE BlackOilPrimaryVariables()
Definition: blackoilprimaryvariables.hh:183
OPM_HOST_DEVICE bool chopAndNormalizeSaturations()
Definition: blackoilprimaryvariables.hh:922
OPM_HOST_DEVICE unsigned pvtRegionIndex() const
Return the index of the region which should be used for PVT properties.
Definition: blackoilprimaryvariables.hh:271
OPM_HOST_DEVICE bool operator==(const BlackOilPrimaryVariables &rhs) const
Definition: blackoilprimaryvariables.hh:1009
void serializeOp(Serializer &serializer)
Definition: blackoilprimaryvariables.hh:997
OPM_HOST_DEVICE void setPrimaryVarsMeaningWater(WaterMeaning newMeaning)
Set the interpretation which should be applied to the switching primary variables.
Definition: blackoilprimaryvariables.hh:285
OPM_HOST_DEVICE void setPrimaryVarsMeaningGas(GasMeaning newMeaning)
Set the interpretation which should be applied to the switching primary variables.
Definition: blackoilprimaryvariables.hh:313
static void registerParameters()
Definition: blackoilprimaryvariables.hh:233
::Opm::BlackOil::BrineMeaning BrineMeaning
Definition: blackoilprimaryvariables.hh:159
BlackOilPrimaryVariables & operator=(const BlackOilPrimaryVariables &other)=default
BlackOilPrimaryVariables(const BlackOilPrimaryVariables &value)=default
Copy constructor.
::Opm::BlackOil::PressureMeaning PressureMeaning
Definition: blackoilprimaryvariables.hh:157
OPM_HOST_DEVICE GasMeaning primaryVarsMeaningGas() const
Return the interpretation which should be applied to the switching primary variables.
Definition: blackoilprimaryvariables.hh:306
OPM_HOST_DEVICE void setPvtRegionIndex(unsigned value)
Set the index of the region which should be used for PVT properties.
Definition: blackoilprimaryvariables.hh:265
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:513
OPM_HOST_DEVICE void assignNaive(const FluidState &fluidState)
Directly retrieve the primary variables from an arbitrary fluid state.
Definition: blackoilprimaryvariables.hh:340
OPM_HOST_DEVICE BrineMeaning primaryVarsMeaningBrine() const
Definition: blackoilprimaryvariables.hh:316
OPM_HOST_DEVICE void setPrimaryVarsMeaningSolvent(SolventMeaning newMeaning)
Set the interpretation which should be applied to the switching primary variables.
Definition: blackoilprimaryvariables.hh:333
OPM_HOST_DEVICE WaterMeaning primaryVarsMeaningWater() const
Return the interpretation which should be applied to the switching primary variables.
Definition: blackoilprimaryvariables.hh:278
static BlackOilPrimaryVariables serializationTestObject()
Definition: blackoilprimaryvariables.hh:194
OPM_HOST_DEVICE Evaluation makeEvaluation(unsigned varIdx, unsigned timeIdx, LinearizationType linearizationType=LinearizationType()) const
Definition: blackoilprimaryvariables.hh:240
OPM_HOST_DEVICE SolventMeaning primaryVarsMeaningSolvent() const
Definition: blackoilprimaryvariables.hh:326
Represents the primary variables used by the a model.
Definition: fvbaseprimaryvariables.hh:54
Definition: blackoilprimaryvariables.hh:66
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
Definition: blackoilprimaryvariables.hh:62
SimpleModularFluidState< double, 3, 3, FluidSystemSimple, false, false, false, false, true, false, false, false > SatOnlyFluidState
Definition: EquilibrationHelpers_impl.hpp:59
Definition: blackoilnewtonmethodparams.hpp:31
Definition: blackoilbioeffectsmodules.hh:45
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:58
static constexpr Scalar value
Definition: blackoilprimaryvariables.hh:58