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