My Project
Loading...
Searching...
No Matches
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/material/common/Valgrind.hpp>
30#include <opm/material/constraintsolvers/NcpFlash.hpp>
31#include <opm/material/fluidsystems/BlackOilFluidSystem.hpp>
32#include <opm/material/fluidstates/CompositionalFluidState.hpp>
33#include <opm/material/fluidstates/SimpleModularFluidState.hpp>
34
43
45
46#include <cstdint>
47
48namespace Opm::Parameters {
49
50template<class Scalar>
51struct PressureScale { static constexpr Scalar value = 1.0; };
52
53} // namespace Opm::Parameters
54
55namespace Opm {
56
62template <class TypeTag>
64{
67
75
76 // number of equations
78
79 // primary variable indices
80 enum { waterSwitchIdx = Indices::waterSwitchIdx };
81 enum { pressureSwitchIdx = Indices::pressureSwitchIdx };
82 enum { compositionSwitchIdx = Indices::compositionSwitchIdx };
83 enum { saltConcentrationIdx = Indices::saltConcentrationIdx };
84 enum { solventSaturationIdx = Indices::solventSaturationIdx };
85
86 static constexpr bool compositionSwitchEnabled = Indices::compositionSwitchIdx >= 0;
87 static constexpr bool waterEnabled = Indices::waterEnabled;
88 static constexpr bool gasEnabled = Indices::gasEnabled;
89 static constexpr bool oilEnabled = Indices::oilEnabled;
90
91 // phase indices from the fluid system
93 enum { gasPhaseIdx = FluidSystem::gasPhaseIdx };
94 enum { waterPhaseIdx = FluidSystem::waterPhaseIdx };
95 enum { oilPhaseIdx = FluidSystem::oilPhaseIdx };
96
97 // component indices from the fluid system
98 enum { numComponents = getPropValue<TypeTag, Properties::NumComponents>() };
99 enum { enableSolvent = getPropValue<TypeTag, Properties::EnableSolvent>() };
100 enum { enableExtbo = getPropValue<TypeTag, Properties::EnableExtbo>() };
101 enum { enablePolymer = getPropValue<TypeTag, Properties::EnablePolymer>() };
102 enum { enableFoam = getPropValue<TypeTag, Properties::EnableFoam>() };
103 enum { enableBrine = getPropValue<TypeTag, Properties::EnableBrine>() };
104 enum { enableSaltPrecipitation = getPropValue<TypeTag, Properties::EnableSaltPrecipitation>() };
105 enum { enableVapwat = getPropValue<TypeTag, Properties::EnableVapwat>() };
106 enum { enableEnergy = getPropValue<TypeTag, Properties::EnableEnergy>() };
107 enum { enableTemperature = getPropValue<TypeTag, Properties::EnableTemperature>() };
108 enum { enableMICP = getPropValue<TypeTag, Properties::EnableMICP>() };
109 enum { gasCompIdx = FluidSystem::gasCompIdx };
110 enum { waterCompIdx = FluidSystem::waterCompIdx };
111 enum { oilCompIdx = FluidSystem::oilCompIdx };
112
113 using Toolbox = MathToolbox<Evaluation>;
114 using ComponentVector = Dune::FieldVector<Scalar, numComponents>;
122
123 static_assert(numPhases == 3, "The black-oil model assumes three phases!");
124 static_assert(numComponents == 3, "The black-oil model assumes three components!");
125
126public:
127 enum class WaterMeaning : std::uint8_t {
128 Sw, // water saturation
129 Rvw, // vaporized water
130 Rsw, // dissolved gas in water
131 Disabled, // The primary variable is not used
132 };
133
134 enum class PressureMeaning : std::uint8_t {
135 Po, // oil pressure
136 Pg, // gas pressure
137 Pw, // water pressure
138 };
139
140 enum class GasMeaning : std::uint8_t {
141 Sg, // gas saturation
142 Rs, // dissolved gas in oil
143 Rv, // vapporized oil
144 Disabled, // The primary variable is not used
145 };
146
147 enum class BrineMeaning : std::uint8_t {
148 Cs, // salt concentration
149 Sp, // (precipitated) salt saturation
150 Disabled, // The primary variable is not used
151 };
152
153 enum class SolventMeaning : std::uint8_t {
154 Ss, // solvent saturation
155 Rsolw, // dissolved solvent in water
156 Disabled, // The primary variable is not used
157 };
158
160 : ParentType()
161 {
162 Valgrind::SetUndefined(*this);
163 pvtRegionIdx_ = 0;
164 }
165
170
171 static BlackOilPrimaryVariables serializationTestObject()
172 {
174 result.pvtRegionIdx_ = 1;
175 result.primaryVarsMeaningBrine_ = BrineMeaning::Sp;
176 result.primaryVarsMeaningGas_ = GasMeaning::Rv;
177 result.primaryVarsMeaningPressure_ = PressureMeaning::Pg;
178 result.primaryVarsMeaningWater_ = WaterMeaning::Rsw;
179 result.primaryVarsMeaningSolvent_ = SolventMeaning::Ss;
180 for (size_t i = 0; i < result.size(); ++i) {
181 result[i] = i+1;
182 }
183
184 return result;
185 }
186
187 static void init()
188 {
189 // TODO: these parameters have undocumented non-trivial dependencies
190 pressureScale_ = Parameters::Get<Parameters::PressureScale<Scalar>>();
191 }
192
193 static void registerParameters()
194 {
195 Parameters::Register<Parameters::PressureScale<Scalar>>
196 ("Scaling of pressure primary variable");
197 }
198
199 void setPressureScale(Scalar val)
200 {
201 pressureScale_ = val;
202 }
203
204 Evaluation
205 makeEvaluation(unsigned varIdx, unsigned timeIdx, LinearizationType linearizationType = LinearizationType()) const
206 {
207 Scalar scale = 1.0;
208 if (varIdx == pressureSwitchIdx) {
209 scale = this->pressureScale_;
210 }
211 if (std::is_same<Evaluation, Scalar>::value)
212 return (*this)[varIdx] * scale; // finite differences
213 else {
214 // automatic differentiation
215 if (timeIdx == linearizationType.time)
216 return Toolbox::createVariable((*this)[varIdx], varIdx) * scale;
217 else
218 return Toolbox::createConstant((*this)[varIdx]) * scale;
219 }
220 }
221
229 void setPvtRegionIndex(unsigned value)
230 { pvtRegionIdx_ = static_cast<unsigned short>(value); }
231
235 unsigned pvtRegionIndex() const
236 { return pvtRegionIdx_; }
237
242 WaterMeaning primaryVarsMeaningWater() const
243 { return primaryVarsMeaningWater_; }
244
250 { primaryVarsMeaningWater_ = newMeaning; }
251
256 PressureMeaning primaryVarsMeaningPressure() const
257 { return primaryVarsMeaningPressure_; }
258
264 { primaryVarsMeaningPressure_ = newMeaning; }
265
270 GasMeaning primaryVarsMeaningGas() const
271 { return primaryVarsMeaningGas_; }
272
278 { primaryVarsMeaningGas_ = newMeaning; }
279
280 BrineMeaning primaryVarsMeaningBrine() const
281 { return primaryVarsMeaningBrine_; }
282
289 { primaryVarsMeaningBrine_ = newMeaning; }
290
291
292 SolventMeaning primaryVarsMeaningSolvent() const
293 { return primaryVarsMeaningSolvent_; }
294
301 { primaryVarsMeaningSolvent_ = newMeaning; }
302
306 template <class FluidState>
307 void assignMassConservative(const FluidState& fluidState,
308 const MaterialLawParams& matParams,
309 bool isInEquilibrium = false)
310 {
311 using ConstEvaluation = typename std::remove_reference<typename FluidState::Scalar>::type;
312 using FsEvaluation = typename std::remove_const<ConstEvaluation>::type;
314
315#ifndef NDEBUG
316 // make sure the temperature is the same in all fluid phases
317 for (unsigned phaseIdx = 1; phaseIdx < numPhases; ++phaseIdx) {
318 Valgrind::CheckDefined(fluidState.temperature(0));
319 Valgrind::CheckDefined(fluidState.temperature(phaseIdx));
320
321 assert(fluidState.temperature(0) == fluidState.temperature(phaseIdx));
322 }
323#endif // NDEBUG
324
325 // for the equilibrium case, we don't need complicated
326 // computations.
327 if (isInEquilibrium) {
328 assignNaive(fluidState);
329 return;
330 }
331
332 // If your compiler bails out here, you're probably not using a suitable black
333 // oil fluid system.
334 typename FluidSystem::template ParameterCache<Scalar> paramCache;
335 paramCache.setRegionIndex(pvtRegionIdx_);
336 paramCache.setMaxOilSat(FsToolbox::value(fluidState.saturation(oilPhaseIdx)));
337
338 // create a mutable fluid state with well defined densities based on the input
339 using NcpFlash = NcpFlash<Scalar, FluidSystem>;
342 fsFlash.setTemperature(FsToolbox::value(fluidState.temperature(/*phaseIdx=*/0)));
343 for (unsigned phaseIdx = 0; phaseIdx < numPhases; ++phaseIdx) {
344 fsFlash.setPressure(phaseIdx, FsToolbox::value(fluidState.pressure(phaseIdx)));
345 fsFlash.setSaturation(phaseIdx, FsToolbox::value(fluidState.saturation(phaseIdx)));
346 for (unsigned compIdx = 0; compIdx < numComponents; ++compIdx)
347 fsFlash.setMoleFraction(phaseIdx, compIdx, FsToolbox::value(fluidState.moleFraction(phaseIdx, compIdx)));
348 }
349
350 paramCache.updateAll(fsFlash);
351 for (unsigned phaseIdx = 0; phaseIdx < numPhases; ++phaseIdx) {
352 if (!FluidSystem::phaseIsActive(phaseIdx))
353 continue;
354
355 Scalar rho = FluidSystem::template density<FlashFluidState, Scalar>(fsFlash, paramCache, phaseIdx);
356 fsFlash.setDensity(phaseIdx, rho);
357 }
358
359 // calculate the "global molarities"
360 ComponentVector globalMolarities(0.0);
361 for (unsigned compIdx = 0; compIdx < numComponents; ++compIdx) {
362 for (unsigned phaseIdx = 0; phaseIdx < numPhases; ++phaseIdx) {
363 if (!FluidSystem::phaseIsActive(phaseIdx))
364 continue;
365
367 fsFlash.saturation(phaseIdx) * fsFlash.molarity(phaseIdx, compIdx);
368 }
369 }
370
371 // use a flash calculation to calculate a fluid state in
372 // thermodynamic equilibrium
373
374 // run the flash calculation
376
377 // use the result to assign the primary variables
379 }
380
384 template <class FluidState>
385 void assignNaive(const FluidState& fluidState)
386 {
387 using ConstEvaluation = typename std::remove_reference<typename FluidState::Scalar>::type;
388 using FsEvaluation = typename std::remove_const<ConstEvaluation>::type;
390
391 bool gasPresent = FluidSystem::phaseIsActive(gasPhaseIdx)?(fluidState.saturation(gasPhaseIdx) > 0.0):false;
392 bool oilPresent = FluidSystem::phaseIsActive(oilPhaseIdx)?(fluidState.saturation(oilPhaseIdx) > 0.0):false;
393 bool waterPresent = FluidSystem::phaseIsActive(waterPhaseIdx)?(fluidState.saturation(waterPhaseIdx) > 0.0):false;
394 const auto& saltSaturation = BlackOil::getSaltSaturation_<FluidSystem, FluidState, Scalar>(fluidState, pvtRegionIdx_);
395 bool precipitatedSaltPresent = enableSaltPrecipitation?(saltSaturation > 0.0):false;
396 bool oneActivePhases = FluidSystem::numActivePhases() == 1;
397 // deal with the primary variables for the energy extension
398 EnergyModule::assignPrimaryVars(*this, fluidState);
399
400 // Determine the meaning of the pressure primary variables
401 // Depending on the phases present, this variable is either interpreted as the
402 // pressure of the oil phase, gas phase (if no oil) or water phase (if only water)
403 if (gasPresent && FluidSystem::enableVaporizedOil() && !oilPresent){
404 primaryVarsMeaningPressure_ = PressureMeaning::Pg;
405 } else if (FluidSystem::phaseIsActive(oilPhaseIdx)) {
406 primaryVarsMeaningPressure_ = PressureMeaning::Po;
407 } else if ( waterPresent && FluidSystem::enableDissolvedGasInWater() && !gasPresent){
408 primaryVarsMeaningPressure_ = PressureMeaning::Pw;
409 } else if (FluidSystem::phaseIsActive(gasPhaseIdx)) {
410 primaryVarsMeaningPressure_ = PressureMeaning::Pg;
411 } else {
412 assert(FluidSystem::phaseIsActive(waterPhaseIdx));
413 primaryVarsMeaningPressure_ = PressureMeaning::Pw;
414 }
415
416 // Determine the meaning of the water primary variables
417 // Depending on the phases present, this variable is either interpreted as
418 // water saturation or vapporized water in the gas phase
419 // For two-phase gas-oil models and one-phase case the variable is disabled.
420 if ( waterPresent && gasPresent ){
421 primaryVarsMeaningWater_ = WaterMeaning::Sw;
422 } else if (gasPresent && FluidSystem::enableVaporizedWater()) {
423 primaryVarsMeaningWater_ = WaterMeaning::Rvw;
424 } else if (waterPresent && FluidSystem::enableDissolvedGasInWater()) {
425 primaryVarsMeaningWater_ = WaterMeaning::Rsw;
426 } else if (FluidSystem::phaseIsActive(waterPhaseIdx) && !oneActivePhases) {
427 primaryVarsMeaningWater_ = WaterMeaning::Sw;
428 } else {
429 primaryVarsMeaningWater_ = WaterMeaning::Disabled;
430 }
431
432 // Determine the meaning of the gas primary variables
433 // Depending on the phases present, this variable is either interpreted as the
434 // saturation of the gas phase, as the fraction of the gas component in the oil
435 // phase (Rs) or as the fraction of the oil component (Rv) in the gas phase.
436 // For two-phase water-oil and water-gas models and one-phase case the variable is disabled.
437 if ( gasPresent && oilPresent ) {
438 primaryVarsMeaningGas_ = GasMeaning::Sg;
439 } else if (oilPresent && FluidSystem::enableDissolvedGas()) {
440 primaryVarsMeaningGas_ = GasMeaning::Rs;
441 } else if (gasPresent && FluidSystem::enableVaporizedOil()){
442 primaryVarsMeaningGas_ = GasMeaning::Rv;
443 } else if (FluidSystem::phaseIsActive(gasPhaseIdx) && FluidSystem::phaseIsActive(oilPhaseIdx)) {
444 primaryVarsMeaningGas_ = GasMeaning::Sg;
445 } else {
446 primaryVarsMeaningGas_ = GasMeaning::Disabled;
447 }
448
449 // Determine the meaning of the brine primary variables
450 if constexpr (enableSaltPrecipitation){
452 primaryVarsMeaningBrine_ = BrineMeaning::Sp;
453 else
454 primaryVarsMeaningBrine_ = BrineMeaning::Cs;
455 } else {
456 primaryVarsMeaningBrine_ = BrineMeaning::Disabled;
457 }
458
459 // assign the actual primary variables
461 case PressureMeaning::Po:
462 this->setScaledPressure_(FsToolbox::value(fluidState.pressure(oilPhaseIdx)));
463 break;
464 case PressureMeaning::Pg:
465 this->setScaledPressure_(FsToolbox::value(fluidState.pressure(gasPhaseIdx)));
466 break;
467 case PressureMeaning::Pw:
468 this->setScaledPressure_(FsToolbox::value(fluidState.pressure(waterPhaseIdx)));
469 break;
470 default:
471 throw std::logic_error("No valid primary variable selected for pressure");
472 }
473 switch(primaryVarsMeaningWater()) {
474 case WaterMeaning::Sw:
475 {
476 (*this)[waterSwitchIdx] = FsToolbox::value(fluidState.saturation(waterPhaseIdx));
477 break;
478 }
479 case WaterMeaning::Rvw:
480 {
481 const auto& rvw = BlackOil::getRvw_<FluidSystem, FluidState, Scalar>(fluidState, pvtRegionIdx_);
482 (*this)[waterSwitchIdx] = rvw;
483 break;
484 }
485 case WaterMeaning::Rsw:
486 {
487 const auto& Rsw = BlackOil::getRsw_<FluidSystem, FluidState, Scalar>(fluidState, pvtRegionIdx_);
488 (*this)[waterSwitchIdx] = Rsw;
489 break;
490 }
491 case WaterMeaning::Disabled:
492 {
493 break;
494 }
495 default:
496 throw std::logic_error("No valid primary variable selected for water");
497 }
498 switch(primaryVarsMeaningGas()) {
499 case GasMeaning::Sg:
500 {
501 (*this)[compositionSwitchIdx] = FsToolbox::value(fluidState.saturation(gasPhaseIdx));
502 break;
503 }
504 case GasMeaning::Rs:
505 {
506 const auto& rs = BlackOil::getRs_<FluidSystem, FluidState, Scalar>(fluidState, pvtRegionIdx_);
507 (*this)[compositionSwitchIdx] = rs;
508 break;
509 }
510 case GasMeaning::Rv:
511 {
512 const auto& rv = BlackOil::getRv_<FluidSystem, FluidState, Scalar>(fluidState, pvtRegionIdx_);
513 (*this)[compositionSwitchIdx] = rv;
514 break;
515 }
516 case GasMeaning::Disabled:
517 {
518 break;
519 }
520 default:
521 throw std::logic_error("No valid primary variable selected for composision");
522 }
523 }
524
536 bool adaptPrimaryVariables(const Problem& problem,
537 unsigned globalDofIdx,
538 [[maybe_unused]] Scalar swMaximum,
539 Scalar thresholdWaterFilledCell, Scalar eps = 0.0)
540 {
541 // this function accesses quite a few black-oil specific low-level functions
542 // directly for better performance (instead of going the canonical way through
543 // the IntensiveQuantities). The reason is that most intensive quantities are not
544 // required to be able to decide if the primary variables needs to be switched or
545 // not, so it would be a waste to compute them.
546
547 // Both the primary variable meaning of water and gas are disabled i.e.
548 // It is a one-phase case and we no variable meaning switch is needed.
549 if (primaryVarsMeaningWater() == WaterMeaning::Disabled && primaryVarsMeaningGas() == GasMeaning::Disabled){
550 return false;
551 }
552
553 // Read the current saturation from the primary variables
554 Scalar sw = 0.0;
555 Scalar sg = 0.0;
556 Scalar saltConcentration = 0.0;
557 const Scalar& T = asImp_().temperature_(problem, globalDofIdx);
558 if (primaryVarsMeaningWater() == WaterMeaning::Sw)
559 sw = (*this)[waterSwitchIdx];
560 if (primaryVarsMeaningGas() == GasMeaning::Sg)
561 sg = (*this)[compositionSwitchIdx];
562 if (primaryVarsMeaningWater() == WaterMeaning::Rsw)
563 sw = 1.0;
564
565 if (primaryVarsMeaningGas() == GasMeaning::Disabled && gasEnabled)
566 sg = 1.0 - sw; // water + gas case
567
568 // if solid phase disappeares: Sp (Solid salt saturation) -> Cs (salt concentration)
569 // if solid phase appears: Cs (salt concentration) -> Sp (Solid salt saturation)
570 if constexpr (enableSaltPrecipitation) {
571 Scalar saltSolubility = BrineModule::saltSol(pvtRegionIndex());
572 if (primaryVarsMeaningBrine() == BrineMeaning::Sp) {
573 saltConcentration = saltSolubility;
574 Scalar saltSat = (*this)[saltConcentrationIdx];
575 if (saltSat < -eps){ //precipitated salt dissappears
576 setPrimaryVarsMeaningBrine(BrineMeaning::Cs);
577 (*this)[saltConcentrationIdx] = saltSolubility; //set salt concentration to solubility limit
578 }
579 }
580 else if (primaryVarsMeaningBrine() == BrineMeaning::Cs) {
581 saltConcentration = (*this)[saltConcentrationIdx];
582 if (saltConcentration > saltSolubility + eps){ //salt concentration exceeds solubility limit
583 setPrimaryVarsMeaningBrine(BrineMeaning::Sp);
584 (*this)[saltConcentrationIdx] = 0.0;
585 }
586 }
587 }
588
589 // if solvent saturation disappeares: Ss (Solvent saturation) -> Rsolw (solvent dissolved in water)
590 // if solvent saturation appears: Rsolw (solvent dissolved in water) -> Ss (Solvent saturation)
591 // Scalar rsolw = 0.0; // not needed at the moment since we dont allow for vapwat in combination with rsolw
592 if constexpr (enableSolvent) {
593 if (SolventModule::isSolubleInWater()) {
594 Scalar p = (*this)[pressureSwitchIdx]; // cap-pressure?
595 Scalar solLimit = SolventModule::solubilityLimit(pvtRegionIndex(), T , p, saltConcentration);
596 if (primaryVarsMeaningSolvent() == SolventMeaning::Ss) {
597 Scalar solSat = (*this)[solventSaturationIdx];
598 if (solSat < -eps){ //solvent dissappears
599 setPrimaryVarsMeaningSolvent(SolventMeaning::Rsolw);
600 (*this)[solventSaturationIdx] = solLimit; //set rsolw to solubility limit
601
602 }
603 }
604 else if (primaryVarsMeaningSolvent() == SolventMeaning::Rsolw) {
605 Scalar rsolw = (*this)[solventSaturationIdx];
606 if (rsolw > solLimit + eps){ //solvent appears as phase
607 setPrimaryVarsMeaningSolvent(SolventMeaning::Ss);
608 (*this)[solventSaturationIdx] = 0.0;
609 }
610 }
611 }
612 }
613
614 // keep track if any meaning has changed
615 bool changed = false;
616
617 // Special case for cells with almost only water
618 // for these cells both saturations (if the phase is enabled) is used
619 // to avoid singular systems.
620 // If dissolved gas in water is enabled we shouldn't enter
621 // here but instead switch to Rsw as primary variable
622 // as sw >= 1.0 -> gas <= 0 (i.e. gas phase disappears)
623 if (sw >= thresholdWaterFilledCell && !FluidSystem::enableDissolvedGasInWater()) {
624
625 // make sure water saturations does not exceed sw_maximum. Default to 1.0
626 if constexpr (waterEnabled) {
627 (*this)[Indices::waterSwitchIdx] = std::min(swMaximum, sw);
628 assert(primaryVarsMeaningWater() == WaterMeaning::Sw);
629 }
630 // the hydrocarbon gas saturation is set to 0.0
631 if constexpr (compositionSwitchEnabled)
632 (*this)[Indices::compositionSwitchIdx] = 0.0;
633
634 changed = primaryVarsMeaningGas() != GasMeaning::Sg;
635 if(changed) {
636 if constexpr (compositionSwitchEnabled)
637 setPrimaryVarsMeaningGas(GasMeaning::Sg);
638
639 // use water pressure?
640 }
641 return changed;
642 }
643
644 if (BrineModule::hasPcfactTables() && primaryVarsMeaningBrine() == BrineMeaning::Sp) {
645 unsigned satnumRegionIdx = problem.satnumRegionIndex(globalDofIdx);
646 Scalar Sp = saltConcentration_();
647 Scalar porosityFactor = min(1.0 - Sp, 1.0); //phi/phi_0
648 const auto& pcfactTable = BrineModule::pcfactTable(satnumRegionIdx);
649 pcFactor_ = pcfactTable.eval(porosityFactor, /*extrapolation=*/true);
650 }
651 else {
652 pcFactor_ = 1.0;
653 }
654
655 switch(primaryVarsMeaningWater()) {
656 case WaterMeaning::Sw:
657 {
658 // if water phase disappeares: Sw (water saturation) -> Rvw (fraction of water in gas phase)
659 if(sw < -eps && sg > eps && FluidSystem::enableVaporizedWater()) {
660 Scalar p = this->pressure_();
661 if(primaryVarsMeaningPressure() == PressureMeaning::Po) {
662 std::array<Scalar, numPhases> pC = { 0.0 };
663 const MaterialLawParams& matParams = problem.materialLawParams(globalDofIdx);
664 Scalar so = 1.0 - sg - solventSaturation_();
665 computeCapillaryPressures_(pC, so, sg + solventSaturation_(), /*sw=*/ 0.0, matParams);
666 p += pcFactor_ * (pC[gasPhaseIdx] - pC[oilPhaseIdx]);
667 }
668 Scalar rvwSat = FluidSystem::gasPvt().saturatedWaterVaporizationFactor(pvtRegionIdx_,
669 T,
670 p,
671 saltConcentration);
672 setPrimaryVarsMeaningWater(WaterMeaning::Rvw);
673 (*this)[Indices::waterSwitchIdx] = rvwSat; //primary variable becomes Rvw
674 changed = true;
675 break;
676 }
677 // if gas phase disappeares: Sw (water saturation) -> Rsw (fraction of gas in water phase)
678 // and Pg (gas pressure) -> Pw ( water pressure)
679 if(sg < -eps && sw > eps && FluidSystem::enableDissolvedGasInWater()) {
680 const Scalar pg = this->pressure_();
681 assert(primaryVarsMeaningPressure() == PressureMeaning::Pg);
682 std::array<Scalar, numPhases> pC = { 0.0 };
683 const MaterialLawParams& matParams = problem.materialLawParams(globalDofIdx);
684 Scalar so = 1.0 - sw - solventSaturation_();
685 computeCapillaryPressures_(pC, so, /*sg=*/ 0.0, sw, matParams);
686 Scalar pw = pg + pcFactor_ * (pC[waterPhaseIdx] - pC[gasPhaseIdx]);
687 Scalar rswSat = FluidSystem::waterPvt().saturatedGasDissolutionFactor(pvtRegionIdx_,
688 T,
689 pw,
690 saltConcentration);
691 setPrimaryVarsMeaningWater(WaterMeaning::Rsw);
692 Scalar rswMax = problem.maxGasDissolutionFactor(/*timeIdx=*/0, globalDofIdx);
693 (*this)[Indices::waterSwitchIdx] = min(rswSat, rswMax); //primary variable becomes Rsw
694 setPrimaryVarsMeaningPressure(PressureMeaning::Pw);
695 this->setScaledPressure_(pw);
696 changed = true;
697 break;
698 }
699 break;
700 }
701 case WaterMeaning::Rvw:
702 {
703 const Scalar& rvw = (*this)[waterSwitchIdx];
704 Scalar p = this->pressure_();
705 if(primaryVarsMeaningPressure() == PressureMeaning::Po) {
706 std::array<Scalar, numPhases> pC = { 0.0 };
707 const MaterialLawParams& matParams = problem.materialLawParams(globalDofIdx);
708 Scalar so = 1.0 - sg - solventSaturation_();
709 computeCapillaryPressures_(pC, so, sg + solventSaturation_(), /*sw=*/ 0.0, matParams);
710 p += pcFactor_ * (pC[gasPhaseIdx] - pC[oilPhaseIdx]);
711 }
712 Scalar rvwSat = FluidSystem::gasPvt().saturatedWaterVaporizationFactor(pvtRegionIdx_,
713 T,
714 p,
715 saltConcentration);
716 // if water phase appears: Rvw (fraction of water in gas phase) -> Sw (water saturation)
717 if (rvw > rvwSat*(1.0 + eps)) {
718 setPrimaryVarsMeaningWater(WaterMeaning::Sw);
719 (*this)[Indices::waterSwitchIdx] = 0.0; // water saturation
720 changed = true;
721 }
722 break;
723 }
724 case WaterMeaning::Rsw:
725 {
726 // Gas phase not present. The hydrocarbon gas phase
727 // appears as soon as more of the gas component is present in the water phase
728 // than what saturated water can hold.
729 const Scalar& pw = this->pressure_();
730 assert(primaryVarsMeaningPressure() == PressureMeaning::Pw);
731 Scalar rswSat = FluidSystem::waterPvt().saturatedGasDissolutionFactor(pvtRegionIdx_,
732 T,
733 pw,
734 saltConcentration);
735
736 Scalar rsw = (*this)[Indices::waterSwitchIdx];
737 Scalar rswMax = problem.maxGasDissolutionFactor(/*timeIdx=*/0, globalDofIdx);
738 if (rsw > min(rswSat, rswMax)) {
739 // the gas phase appears, i.e., switch the primary variables to WaterMeaning::Sw
740 setPrimaryVarsMeaningWater(WaterMeaning::Sw);
741 (*this)[Indices::waterSwitchIdx] = 1.0; // hydrocarbon water saturation
742 setPrimaryVarsMeaningPressure(PressureMeaning::Pg);
743 std::array<Scalar, numPhases> pC = { 0.0 };
744 const MaterialLawParams& matParams = problem.materialLawParams(globalDofIdx);
745 computeCapillaryPressures_(pC, /*so=*/ 0.0, /*sg=*/ 0.0, /*sw=*/ 1.0, matParams);
746 Scalar pg = pw + pcFactor_ * (pC[gasPhaseIdx] - pC[waterPhaseIdx]);
747 this->setScaledPressure_(pg);
748 changed = true;
749 }
750 break;
751 }
752 case WaterMeaning::Disabled:
753 {
754 break;
755 }
756 default:
757 throw std::logic_error("No valid primary variable selected for water");
758 }
759
760
761 // if gas phase disappeares: Sg (gas saturation) -> Rs (fraction of gas in oil phase)
762 // if oil phase disappeares: Sg (gas saturation) -> Rv (fraction of oil in gas phase)
763 // Po (oil pressure ) -> Pg (gas pressure)
764
765 // if gas phase appears: Rs (fraction of gas in oil phase) -> Sg (gas saturation)
766 // if oil phase appears: Rv (fraction of oil in gas phase) -> Sg (gas saturation)
767 // Pg (gas pressure ) -> Po (oil pressure)
768 switch(primaryVarsMeaningGas()) {
769 case GasMeaning::Sg:
770 {
771 Scalar s = 1.0 - sw - solventSaturation_();
772 if (sg < -eps && s > 0.0 && FluidSystem::enableDissolvedGas()) {
773 const Scalar po = this->pressure_();
774 setPrimaryVarsMeaningGas(GasMeaning::Rs);
775 Scalar soMax = std::max(s, problem.maxOilSaturation(globalDofIdx));
776 Scalar rsMax = problem.maxGasDissolutionFactor(/*timeIdx=*/0, globalDofIdx);
777 Scalar rsSat = enableExtbo ? ExtboModule::rs(pvtRegionIndex(),
778 po,
779 zFraction_())
780 : FluidSystem::oilPvt().saturatedGasDissolutionFactor(pvtRegionIdx_,
781 T,
782 po,
783 s,
784 soMax);
785 (*this)[Indices::compositionSwitchIdx] = std::min(rsMax, rsSat);
786 changed = true;
787 }
788 Scalar so = 1.0 - sw - solventSaturation_() - sg;
789 if (so < -eps && sg > 0.0 && FluidSystem::enableVaporizedOil()) {
790 // the oil phase disappeared and some hydrocarbon gas phase is still
791 // present, i.e., switch the primary variables to GasMeaning::Rv.
792 // we only have the oil pressure readily available, but we need the gas
793 // pressure, i.e. we must determine capillary pressure
794 const Scalar po = this->pressure_();
795 std::array<Scalar, numPhases> pC = { 0.0 };
796 const MaterialLawParams& matParams = problem.materialLawParams(globalDofIdx);
797 computeCapillaryPressures_(pC, /*so=*/0.0, sg + solventSaturation_(), sw, matParams);
798 Scalar pg = po + pcFactor_ * (pC[gasPhaseIdx] - pC[oilPhaseIdx]);
799
800 // we start at the GasMeaning::Rv value that corresponds to that of oil-saturated
801 // hydrocarbon gas
802 setPrimaryVarsMeaningPressure(PressureMeaning::Pg);
803 this->setScaledPressure_(pg);
804 Scalar soMax = problem.maxOilSaturation(globalDofIdx);
805 Scalar rvMax = problem.maxOilVaporizationFactor(/*timeIdx=*/0, globalDofIdx);
806 Scalar rvSat = enableExtbo ? ExtboModule::rv(pvtRegionIndex(),
807 pg,
808 zFraction_())
809 : FluidSystem::gasPvt().saturatedOilVaporizationFactor(pvtRegionIdx_,
810 T,
811 pg,
812 Scalar(0),
813 soMax);
814 setPrimaryVarsMeaningGas(GasMeaning::Rv);
815 (*this)[Indices::compositionSwitchIdx] = std::min(rvMax, rvSat);
816 changed = true;
817 }
818 break;
819 }
820 case GasMeaning::Rs:
821 {
822 // Gas phase not present. The hydrocarbon gas phase
823 // appears as soon as more of the gas component is present in the oil phase
824 // than what saturated oil can hold.
825 const Scalar po = this->pressure_();
826 Scalar so = 1.0 - sw - solventSaturation_();
827 Scalar soMax = std::max(so, problem.maxOilSaturation(globalDofIdx));
828 Scalar rsMax = problem.maxGasDissolutionFactor(/*timeIdx=*/0, globalDofIdx);
829 Scalar rsSat = enableExtbo ? ExtboModule::rs(pvtRegionIndex(),
830 po,
831 zFraction_())
832 : FluidSystem::oilPvt().saturatedGasDissolutionFactor(pvtRegionIdx_,
833 T,
834 po,
835 so,
836 soMax);
837
838 Scalar rs = (*this)[Indices::compositionSwitchIdx];
839 if (rs > std::min(rsMax, rsSat*(Scalar{1.0} + eps))) {
840 // the gas phase appears, i.e., switch the primary variables to GasMeaning::Sg
841 setPrimaryVarsMeaningGas(GasMeaning::Sg);
842 (*this)[Indices::compositionSwitchIdx] = 0.0; // hydrocarbon gas saturation
843 changed = true;
844 }
845 break;
846 }
847 case GasMeaning::Rv:
848 {
849 // The oil phase appears as
850 // soon as more of the oil component is present in the hydrocarbon gas phase
851 // than what saturated gas contains. Note that we use the blackoil specific
852 // low-level PVT objects here for performance reasons.
853 const Scalar pg = this->pressure_();
854 Scalar soMax = problem.maxOilSaturation(globalDofIdx);
855 Scalar rvMax = problem.maxOilVaporizationFactor(/*timeIdx=*/0, globalDofIdx);
856 Scalar rvSat = enableExtbo ? ExtboModule::rv(pvtRegionIndex(),
857 pg,
858 zFraction_())
859 : FluidSystem::gasPvt().saturatedOilVaporizationFactor(pvtRegionIdx_,
860 T,
861 pg,
862 /*so=*/Scalar(0.0),
863 soMax);
864
865 Scalar rv = (*this)[Indices::compositionSwitchIdx];
866 if (rv > std::min(rvMax, rvSat*(Scalar{1.0} + eps))) {
867 // switch to phase equilibrium mode because the oil phase appears. here
868 // we also need the capillary pressures to calculate the oil phase
869 // pressure using the gas phase pressure
870 Scalar sg2 = 1.0 - sw - solventSaturation_();
871 std::array<Scalar, numPhases> pC = { 0.0 };
872 const MaterialLawParams& matParams = problem.materialLawParams(globalDofIdx);
873 computeCapillaryPressures_(pC,
874 /*so=*/0.0,
875 /*sg=*/sg2 + solventSaturation_(),
876 sw,
877 matParams);
878 Scalar po = pg + pcFactor_ * (pC[oilPhaseIdx] - pC[gasPhaseIdx]);
879
880 setPrimaryVarsMeaningGas(GasMeaning::Sg);
881 setPrimaryVarsMeaningPressure(PressureMeaning::Po);
882 this->setScaledPressure_(po);
883 (*this)[Indices::compositionSwitchIdx] = sg2; // hydrocarbon gas saturation
884 changed = true;
885 }
886 break;
887 }
888 case GasMeaning::Disabled:
889 {
890 break;
891 }
892 default:
893 throw std::logic_error("No valid primary variable selected for water");
894 }
895 return changed;
896 }
897
898 bool chopAndNormalizeSaturations(){
899 if (primaryVarsMeaningWater() == WaterMeaning::Disabled &&
900 primaryVarsMeaningGas() == GasMeaning::Disabled){
901 return false;
902 }
903 Scalar sw = 0.0;
904 if (primaryVarsMeaningWater() == WaterMeaning::Sw)
905 sw = (*this)[Indices::waterSwitchIdx];
906 Scalar sg = 0.0;
907 if (primaryVarsMeaningGas() == GasMeaning::Sg)
908 sg = (*this)[Indices::compositionSwitchIdx];
909
910 Scalar ssol = 0.0;
911 if (primaryVarsMeaningSolvent() == SolventMeaning::Ss)
912 ssol =(*this) [Indices::solventSaturationIdx];
913
914 Scalar so = 1.0 - sw - sg - ssol;
915 sw = std::min(std::max(sw, Scalar{0.0}), Scalar{1.0});
916 so = std::min(std::max(so, Scalar{0.0}), Scalar{1.0});
917 sg = std::min(std::max(sg, Scalar{0.0}), Scalar{1.0});
918 ssol = std::min(std::max(ssol, Scalar{0.0}), Scalar{1.0});
919 Scalar st = sw + so + sg + ssol;
920 sw = sw/st;
921 sg = sg/st;
922 ssol = ssol/st;
923 assert(st>0.5);
924 if (primaryVarsMeaningWater() == WaterMeaning::Sw)
925 (*this)[Indices::waterSwitchIdx] = sw;
926 if (primaryVarsMeaningGas() == GasMeaning::Sg)
927 (*this)[Indices::compositionSwitchIdx] = sg;
928 if (primaryVarsMeaningSolvent() == SolventMeaning::Ss)
929 (*this) [Indices::solventSaturationIdx] = ssol;
930
931 return !(st==1);
932 }
933
934 BlackOilPrimaryVariables& operator=(const BlackOilPrimaryVariables& other) = default;
935
936 using ParentType::operator=;
937
945 void checkDefined() const
946 {
947#ifndef NDEBUG
948 // check the "real" primary variables
949 for (unsigned i = 0; i < this->size(); ++i)
950 Valgrind::CheckDefined((*this)[i]);
951
952 // check the "pseudo" primary variables
953 Valgrind::CheckDefined(primaryVarsMeaningWater_);
954 Valgrind::CheckDefined(primaryVarsMeaningGas_);
955 Valgrind::CheckDefined(primaryVarsMeaningPressure_);
956 Valgrind::CheckDefined(primaryVarsMeaningBrine_);
957 Valgrind::CheckDefined(primaryVarsMeaningSolvent_);
958
959 Valgrind::CheckDefined(pvtRegionIdx_);
960#endif // NDEBUG
961 }
962
963 template<class Serializer>
964 void serializeOp(Serializer& serializer)
965 {
966 using FV = Dune::FieldVector<Scalar, getPropValue<TypeTag, Properties::NumEq>()>;
967 serializer(static_cast<FV&>(*this));
968 serializer(primaryVarsMeaningWater_);
969 serializer(primaryVarsMeaningPressure_);
970 serializer(primaryVarsMeaningGas_);
971 serializer(primaryVarsMeaningBrine_);
972 serializer(primaryVarsMeaningSolvent_);
973 serializer(pvtRegionIdx_);
974 }
975
976 bool operator==(const BlackOilPrimaryVariables& rhs) const
977 {
978 return static_cast<const FvBasePrimaryVariables<TypeTag>&>(*this) == rhs &&
979 this->primaryVarsMeaningWater_ == rhs.primaryVarsMeaningWater_ &&
980 this->primaryVarsMeaningPressure_ == rhs.primaryVarsMeaningPressure_ &&
981 this->primaryVarsMeaningGas_ == rhs.primaryVarsMeaningGas_ &&
982 this->primaryVarsMeaningBrine_ == rhs.primaryVarsMeaningBrine_ &&
983 this->primaryVarsMeaningSolvent_ == rhs.primaryVarsMeaningSolvent_ &&
984 this->pvtRegionIdx_ == rhs.pvtRegionIdx_;
985 }
986
987private:
988 Implementation& asImp_()
989 { return *static_cast<Implementation*>(this); }
990
991 const Implementation& asImp_() const
992 { return *static_cast<const Implementation*>(this); }
993
994 Scalar solventSaturation_() const
995 {
996 if constexpr (enableSolvent) {
997 if ( primaryVarsMeaningSolvent() == SolventMeaning::Ss)
998 return (*this)[Indices::solventSaturationIdx];
999 }
1000 return 0.0;
1001 }
1002
1003 Scalar zFraction_() const
1004 {
1005 if constexpr (enableExtbo)
1006 return (*this)[Indices::zFractionIdx];
1007 else
1008 return 0.0;
1009 }
1010
1011 Scalar polymerConcentration_() const
1012 {
1013 if constexpr (enablePolymer)
1014 return (*this)[Indices::polymerConcentrationIdx];
1015 else
1016 return 0.0;
1017 }
1018
1019 Scalar foamConcentration_() const
1020 {
1021 if constexpr (enableFoam)
1022 return (*this)[Indices::foamConcentrationIdx];
1023 else
1024 return 0.0;
1025 }
1026
1027 Scalar saltConcentration_() const
1028 {
1029 if constexpr (enableBrine)
1030 return (*this)[Indices::saltConcentrationIdx];
1031 else
1032 return 0.0;
1033 }
1034
1035 Scalar temperature_(const Problem& problem, [[maybe_unused]] unsigned globalDofIdx) const
1036 {
1037 if constexpr (enableEnergy)
1038 return (*this)[Indices::temperatureIdx];
1039 else if constexpr( enableTemperature)
1040 return problem.temperature(globalDofIdx, /*timeIdx*/ 0);
1041
1042 else
1043 return FluidSystem::reservoirTemperature();
1044 }
1045
1046 Scalar microbialConcentration_() const
1047 {
1048 if constexpr (enableMICP)
1049 return (*this)[Indices::microbialConcentrationIdx];
1050 else
1051 return 0.0;
1052 }
1053
1054 Scalar oxygenConcentration_() const
1055 {
1056 if constexpr (enableMICP)
1057 return (*this)[Indices::oxygenConcentrationIdx];
1058 else
1059 return 0.0;
1060 }
1061
1062 Scalar ureaConcentration_() const
1063 {
1064 if constexpr (enableMICP)
1065 return (*this)[Indices::ureaConcentrationIdx];
1066 else
1067 return 0.0;
1068 }
1069
1070 Scalar biofilmConcentration_() const
1071 {
1072 if constexpr (enableMICP)
1073 return (*this)[Indices::biofilmConcentrationIdx];
1074 else
1075 return 0.0;
1076 }
1077
1078 Scalar calciteConcentration_() const
1079 {
1080 if constexpr (enableMICP)
1081 return (*this)[Indices::calciteConcentrationIdx];
1082 else
1083 return 0.0;
1084 }
1085
1086 template <class Container>
1087 void computeCapillaryPressures_(Container& result,
1088 Scalar so,
1089 Scalar sg,
1090 Scalar sw,
1091 const MaterialLawParams& matParams) const
1092 {
1093 using SatOnlyFluidState = SimpleModularFluidState<Scalar,
1094 numPhases,
1095 numComponents,
1096 FluidSystem,
1097 /*storePressure=*/false,
1098 /*storeTemperature=*/false,
1099 /*storeComposition=*/false,
1100 /*storeFugacity=*/false,
1101 /*storeSaturation=*/true,
1102 /*storeDensity=*/false,
1103 /*storeViscosity=*/false,
1104 /*storeEnthalpy=*/false>;
1105 SatOnlyFluidState fluidState;
1106 fluidState.setSaturation(waterPhaseIdx, sw);
1107 fluidState.setSaturation(oilPhaseIdx, so);
1108 fluidState.setSaturation(gasPhaseIdx, sg);
1109
1110 MaterialLaw::capillaryPressures(result, matParams, fluidState);
1111 }
1112
1113 Scalar pressure_() const
1114 {
1115 return (*this)[Indices::pressureSwitchIdx] * this->pressureScale_;
1116 }
1117
1118 void setScaledPressure_(Scalar pressure)
1119 {
1120 (*this)[Indices::pressureSwitchIdx] = pressure / (this->pressureScale_);
1121 }
1122
1123 WaterMeaning primaryVarsMeaningWater_{WaterMeaning::Disabled};
1124 PressureMeaning primaryVarsMeaningPressure_{PressureMeaning::Po};
1125 GasMeaning primaryVarsMeaningGas_{GasMeaning::Disabled};
1126 BrineMeaning primaryVarsMeaningBrine_{BrineMeaning::Disabled};
1127 SolventMeaning primaryVarsMeaningSolvent_{SolventMeaning::Disabled};
1128 unsigned short pvtRegionIdx_;
1129 Scalar pcFactor_;
1130 static inline Scalar pressureScale_ = 1.0;
1131};
1132
1133} // namespace Opm
1134
1135#endif
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.
Contains the classes required to extend the black-oil model to include the effects of foam.
Contains the classes required to extend the black-oil model by MICP.
Contains the classes required to extend the black-oil model by polymer.
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 brine.
Definition blackoilbrinemodules.hh:50
Contains the high level supplements required to extend the black oil model by energy.
Definition blackoilenergymodules.hh:52
static void assignPrimaryVars(PrimaryVariables &priVars, Scalar)
Assign the energy specific primary variables to a PrimaryVariables object.
Definition blackoilenergymodules.hh:247
Contains the high level supplements required to extend the black oil model.
Definition blackoilextbomodules.hh:59
Contains the high level supplements required to extend the black oil model to include the effects of ...
Definition blackoilfoammodules.hh:60
Contains the high level supplements required to extend the black oil model by MICP.
Definition blackoilmicpmodules.hh:49
Contains the high level supplements required to extend the black oil model by polymer.
Definition blackoilpolymermodules.hh:54
Represents the primary variables used by the black-oil model.
Definition blackoilprimaryvariables.hh:64
unsigned pvtRegionIndex() const
Return the index of the region which should be used for PVT properties.
Definition blackoilprimaryvariables.hh:235
GasMeaning primaryVarsMeaningGas() const
Return the interpretation which should be applied to the switching primary variables.
Definition blackoilprimaryvariables.hh:270
PressureMeaning primaryVarsMeaningPressure() const
Return the interpretation which should be applied to the switching primary variables.
Definition blackoilprimaryvariables.hh:256
void setPrimaryVarsMeaningSolvent(SolventMeaning newMeaning)
Set the interpretation which should be applied to the switching primary variables.
Definition blackoilprimaryvariables.hh:300
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:536
void setPrimaryVarsMeaningPressure(PressureMeaning newMeaning)
Set the interpretation which should be applied to the switching primary variables.
Definition blackoilprimaryvariables.hh:263
WaterMeaning primaryVarsMeaningWater() const
Return the interpretation which should be applied to the switching primary variables.
Definition blackoilprimaryvariables.hh:242
void setPrimaryVarsMeaningWater(WaterMeaning newMeaning)
Set the interpretation which should be applied to the switching primary variables.
Definition blackoilprimaryvariables.hh:249
void assignNaive(const FluidState &fluidState)
Directly retrieve the primary variables from an arbitrary fluid state.
Definition blackoilprimaryvariables.hh:385
void assignMassConservative(const FluidState &fluidState, const MaterialLawParams &matParams, bool isInEquilibrium=false)
< Import base class assignment operators.
Definition blackoilprimaryvariables.hh:307
void setPrimaryVarsMeaningBrine(BrineMeaning newMeaning)
Set the interpretation which should be applied to the switching primary variables.
Definition blackoilprimaryvariables.hh:288
BlackOilPrimaryVariables(const BlackOilPrimaryVariables &value)=default
Copy constructor.
void setPrimaryVarsMeaningGas(GasMeaning newMeaning)
Set the interpretation which should be applied to the switching primary variables.
Definition blackoilprimaryvariables.hh:277
void setPvtRegionIndex(unsigned value)
Set the index of the region which should be used for PVT properties.
Definition blackoilprimaryvariables.hh:229
void checkDefined() const
< Import base class assignment operators.
Definition blackoilprimaryvariables.hh:945
Contains the high level supplements required to extend the black oil model by solvents.
Definition blackoilsolventmodules.hh:58
Represents the primary variables used by the a model.
Definition fvbaseprimaryvariables.hh:52
Represents the primary variables used by the a model.
This file contains a set of helper functions used by VFPProd / VFPInj.
Definition blackoilboundaryratevector.hh:37
constexpr auto getPropValue()
get the value data member of a property
Definition propertysystem.hh:242
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:235
Definition blackoilprimaryvariables.hh:51