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