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