opm-simulators
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 
40 #include <opm/models/blackoil/blackoilmeanings.hh>
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 
55 namespace Opm::Parameters {
56 
57 template<class Scalar>
59 { static constexpr Scalar value = 1.0; };
60 
61 } // namespace Opm::Parameters
62 
63 namespace Opm {
64 
70 template <class TypeTag, template<class, int> class VectorType = Dune::FieldVector>
71 class 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 
132 public:
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.
136  using WaterMeaning = ::Opm::BlackOil::WaterMeaning;
137  using PressureMeaning = ::Opm::BlackOil::PressureMeaning;
138  using GasMeaning = ::Opm::BlackOil::GasMeaning;
139  using BrineMeaning = ::Opm::BlackOil::BrineMeaning;
140  using SolventMeaning = ::Opm::BlackOil::SolventMeaning;
141 
142  // Allow conversion between different vector types
143  template<class OtherTypeTag, template<class, int> class OtherVectorType>
144  friend class BlackOilPrimaryVariables;
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 
172  BlackOilPrimaryVariables(const BlackOilPrimaryVariables& value) = default;
173 
174  static BlackOilPrimaryVariables serializationTestObject()
175  {
176  BlackOilPrimaryVariables result;
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 
272  OPM_HOST_DEVICE PressureMeaning primaryVarsMeaningPressure() const
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 
306  OPM_HOST_DEVICE SolventMeaning primaryVarsMeaningSolvent() const
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::ValueType>;
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);
515  if (primaryVarsMeaningWater() == WaterMeaning::Sw) {
516  sw = (*this)[waterSwitchIdx];
517  }
518  if (primaryVarsMeaningGas() == GasMeaning::Sg) {
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) {
554  if (SolventModule::isSolubleInWater()) {
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);
588  assert(primaryVarsMeaningWater() == WaterMeaning::Sw);
589  }
590  // the hydrocarbon gas saturation is set to 0.0
591  if constexpr (compositionSwitchEnabled) {
592  (*this)[Indices::compositionSwitchIdx] = 0.0;
593  }
594 
595  changed = primaryVarsMeaningGas() != GasMeaning::Sg;
596  if (changed) {
597  if constexpr (compositionSwitchEnabled) {
598  setPrimaryVarsMeaningGas(GasMeaning::Sg);
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)) {
693  setPrimaryVarsMeaningWater(WaterMeaning::Sw);
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
716  setPrimaryVarsMeaningWater(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_();
747  setPrimaryVarsMeaningGas(GasMeaning::Rs);
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);
787  setPrimaryVarsMeaningGas(GasMeaning::Rv);
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
814  setPrimaryVarsMeaningGas(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 
853  setPrimaryVarsMeaningGas(GasMeaning::Sg);
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;
877  if (primaryVarsMeaningWater() == WaterMeaning::Sw) {
878  sw = (*this)[Indices::waterSwitchIdx];
879  }
880  Scalar sg = 0.0;
881  if (primaryVarsMeaningGas() == GasMeaning::Sg) {
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);
900  if (primaryVarsMeaningWater() == WaterMeaning::Sw) {
901  (*this)[Indices::waterSwitchIdx] = sw;
902  }
903  if (primaryVarsMeaningGas() == GasMeaning::Sg) {
904  (*this)[Indices::compositionSwitchIdx] = sg;
905  }
906  if (primaryVarsMeaningSolvent() == SolventMeaning::Ss) {
907  (*this) [Indices::solventSaturationIdx] = ssol;
908  }
909 
910  return (st != 1);
911  }
912 
913  BlackOilPrimaryVariables& operator=(const BlackOilPrimaryVariables& other) = default;
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 
968 private:
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
OPM_HOST_DEVICE void setPrimaryVarsMeaningGas(GasMeaning newMeaning)
Set the interpretation which should be applied to the switching primary variables.
Definition: blackoilprimaryvariables.hh:293
Contains the high level supplements required to extend the black oil model by solvents.
Definition: blackoilsolventmodules.hh:68
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
Contains the classes required to extend the black-oil model by solvent component. ...
Definition: blackoilprimaryvariables.hh:58
OPM_HOST_DEVICE GasMeaning primaryVarsMeaningGas() const
Return the interpretation which should be applied to the switching primary variables.
Definition: blackoilprimaryvariables.hh:286
bool adaptPrimaryVariables(const Problem &problem, unsigned globalDofIdx, [[maybe_unused]] Scalar swMaximum, Scalar thresholdWaterFilledCell, Scalar eps=0.0)
Adapt the interpretation of the switching variables to be physically meaningful.
Definition: blackoilprimaryvariables.hh:491
Contains the classes required to extend the black-oil model by solvents.
OPM_HOST_DEVICE void setPrimaryVarsMeaningPressure(PressureMeaning newMeaning)
Set the interpretation which should be applied to the switching primary variables.
Definition: blackoilprimaryvariables.hh:279
Contains the high level supplements required to extend the black oil model by brine.
Definition: blackoilbrinemodules.hh:57
This file contains a set of helper functions used by VFPProd / VFPInj.
Definition: blackoilbioeffectsmodules.hh:45
Definition: blackoilnewtonmethodparams.hpp:31
Contains the high level supplements required to extend the black oil model by energy.
Definition: blackoilenergymodules.hh:62
OPM_HOST_DEVICE void setPrimaryVarsMeaningSolvent(SolventMeaning newMeaning)
Set the interpretation which should be applied to the switching primary variables.
Definition: blackoilprimaryvariables.hh:313
Declares the properties required by the black oil model.
Represents the primary variables used by the a model.
Definition: fvbaseprimaryvariables.hh:51
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 BlackOilPrimaryVariables(const BlackOilPrimaryVariables< OtherTypeTag, OtherVectorType > &other)
Assignment from another primary variables object.
Definition: blackoilprimaryvariables.hh:151
Contains the classes required to extend the black-oil model by brine.
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 setPvtRegionIndex(unsigned value)
Set the index of the region which should be used for PVT properties.
Definition: blackoilprimaryvariables.hh:245
Represents the primary variables used by the black-oil model.
Definition: blackoilprimaryvariables.hh:71
OPM_HOST_DEVICE PressureMeaning primaryVarsMeaningPressure() const
Return the interpretation which should be applied to the switching primary variables.
Definition: blackoilprimaryvariables.hh:272
OPM_HOST_DEVICE WaterMeaning primaryVarsMeaningWater() const
Return the interpretation which should be applied to the switching primary variables.
Definition: blackoilprimaryvariables.hh:258
static void assignPrimaryVars(PrimaryVariables &priVars, const FluidState &fluidState)
Assign the energy specific primary variables to a PrimaryVariables object.
Definition: blackoilenergymodules.hh:273
Represents the primary variables used by the a model.
Contains the high level supplements required to extend the black oil model.
Definition: blackoilextbomodules.hh:63
OPM_HOST_DEVICE void assignNaive(const FluidState &fluidState)
Directly retrieve the primary variables from an arbitrary fluid state.
Definition: blackoilprimaryvariables.hh:320
Contains the classes required to extend the black-oil model by bioeffects.
OPM_HOST_DEVICE void setPrimaryVarsMeaningBrine(BrineMeaning newMeaning)
Set the interpretation which should be applied to the switching primary variables.
Definition: blackoilprimaryvariables.hh:303
Contains the classes required to extend the black-oil model by energy.
OPM_HOST_DEVICE void checkDefined() const
< Import base class assignment operators.
Definition: blackoilprimaryvariables.hh:924
Contains the high level supplements required to extend the black oil model by bioeffects.
Definition: blackoilbioeffectsmodules.hh:94