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 
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 
38 #include <opm/models/blackoil/blackoilmeanings.hh>
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 
53 namespace Opm::Parameters {
54 
55 template<class Scalar>
57 { static constexpr Scalar value = 1.0; };
58 
59 } // namespace Opm::Parameters
60 
61 namespace Opm {
62 
68 template <class TypeTag, template<class, int> class VectorType = Dune::FieldVector>
69 class 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 
135 public:
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.
139  using WaterMeaning = ::Opm::BlackOil::WaterMeaning;
140  using PressureMeaning = ::Opm::BlackOil::PressureMeaning;
141  using GasMeaning = ::Opm::BlackOil::GasMeaning;
142  using BrineMeaning = ::Opm::BlackOil::BrineMeaning;
143  using SolventMeaning = ::Opm::BlackOil::SolventMeaning;
144 
145  // Allow conversion between different vector types
146  template<class OtherTypeTag, template<class, int> class OtherVectorType>
147  friend class BlackOilPrimaryVariables;
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 
175  BlackOilPrimaryVariables(const BlackOilPrimaryVariables& value) = default;
176 
177  static BlackOilPrimaryVariables serializationTestObject()
178  {
179  BlackOilPrimaryVariables result;
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 
275  OPM_HOST_DEVICE PressureMeaning primaryVarsMeaningPressure() const
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 
309  OPM_HOST_DEVICE SolventMeaning primaryVarsMeaningSolvent() const
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);
520  if (primaryVarsMeaningWater() == WaterMeaning::Sw) {
521  sw = (*this)[waterSwitchIdx];
522  }
523  if (primaryVarsMeaningGas() == GasMeaning::Sg) {
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);
593  assert(primaryVarsMeaningWater() == WaterMeaning::Sw);
594  }
595  // the hydrocarbon gas saturation is set to 0.0
596  if constexpr (compositionSwitchEnabled) {
597  (*this)[Indices::compositionSwitchIdx] = 0.0;
598  }
599 
600  changed = primaryVarsMeaningGas() != GasMeaning::Sg;
601  if (changed) {
602  if constexpr (compositionSwitchEnabled) {
603  setPrimaryVarsMeaningGas(GasMeaning::Sg);
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)) {
698  setPrimaryVarsMeaningWater(WaterMeaning::Sw);
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
721  setPrimaryVarsMeaningWater(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_();
752  setPrimaryVarsMeaningGas(GasMeaning::Rs);
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  }
798  setPrimaryVarsMeaningGas(GasMeaning::Rv);
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
827  setPrimaryVarsMeaningGas(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 
868  setPrimaryVarsMeaningGas(GasMeaning::Sg);
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;
892  if (primaryVarsMeaningWater() == WaterMeaning::Sw) {
893  sw = (*this)[Indices::waterSwitchIdx];
894  }
895  Scalar sg = 0.0;
896  if (primaryVarsMeaningGas() == GasMeaning::Sg) {
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);
915  if (primaryVarsMeaningWater() == WaterMeaning::Sw) {
916  (*this)[Indices::waterSwitchIdx] = sw;
917  }
918  if (primaryVarsMeaningGas() == GasMeaning::Sg) {
919  (*this)[Indices::compositionSwitchIdx] = sg;
920  }
921  if (primaryVarsMeaningSolvent() == SolventMeaning::Ss) {
922  (*this) [Indices::solventSaturationIdx] = ssol;
923  }
924 
925  return (st != 1);
926  }
927 
928  BlackOilPrimaryVariables& operator=(const BlackOilPrimaryVariables& other) = default;
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 
983 private:
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
OPM_HOST_DEVICE void setPrimaryVarsMeaningGas(GasMeaning newMeaning)
Set the interpretation which should be applied to the switching primary variables.
Definition: blackoilprimaryvariables.hh:296
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: blackoilprimaryvariables.hh:56
OPM_HOST_DEVICE GasMeaning primaryVarsMeaningGas() const
Return the interpretation which should be applied to the switching primary variables.
Definition: blackoilprimaryvariables.hh:289
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:496
OPM_HOST_DEVICE void setPrimaryVarsMeaningPressure(PressureMeaning newMeaning)
Set the interpretation which should be applied to the switching primary variables.
Definition: blackoilprimaryvariables.hh:282
Structs needed for tpfalinearizer and its gpuparams struct extracted to be defined in one place that ...
Definition: blackoilbioeffectsmodules.hh:45
Contains classes extending the black-oil model.
Definition: blackoilnewtonmethodparams.hpp:31
Definition: blackoilmodules.hpp:62
OPM_HOST_DEVICE void setPrimaryVarsMeaningSolvent(SolventMeaning newMeaning)
Set the interpretation which should be applied to the switching primary variables.
Definition: blackoilprimaryvariables.hh:316
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:254
OPM_HOST_DEVICE BlackOilPrimaryVariables(const BlackOilPrimaryVariables< OtherTypeTag, OtherVectorType > &other)
Assignment from another primary variables object.
Definition: blackoilprimaryvariables.hh:154
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 setPvtRegionIndex(unsigned value)
Set the index of the region which should be used for PVT properties.
Definition: blackoilprimaryvariables.hh:248
Represents the primary variables used by the black-oil model.
Definition: blackoilprimaryvariables.hh:69
OPM_HOST_DEVICE PressureMeaning primaryVarsMeaningPressure() const
Return the interpretation which should be applied to the switching primary variables.
Definition: blackoilprimaryvariables.hh:275
OPM_HOST_DEVICE WaterMeaning primaryVarsMeaningWater() const
Return the interpretation which should be applied to the switching primary variables.
Definition: blackoilprimaryvariables.hh:261
Represents the primary variables used by the a model.
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 void setPrimaryVarsMeaningBrine(BrineMeaning newMeaning)
Set the interpretation which should be applied to the switching primary variables.
Definition: blackoilprimaryvariables.hh:306
OPM_HOST_DEVICE void checkDefined() const
< Import base class assignment operators.
Definition: blackoilprimaryvariables.hh:939