blackoilintensivequantities.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
6 OPM is free software: you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation, either version 2 of the License, or
9 (at your option) any later version.
10
11 OPM is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
15
16 You should have received a copy of the GNU General Public License
17 along with OPM. If not, see <http://www.gnu.org/licenses/>.
18
19 Consult the COPYING file in the top-level source directory of this
20 module for the precise wording of the license and the list of
21 copyright holders.
22*/
28#ifndef EWOMS_BLACK_OIL_INTENSIVE_QUANTITIES_HH
29#define EWOMS_BLACK_OIL_INTENSIVE_QUANTITIES_HH
30
31#include <dune/common/fmatrix.hh>
32
33#include <opm/common/ErrorMacros.hpp>
34#include <opm/common/TimingMacros.hpp>
35#include <opm/common/utility/gpuDecorators.hpp>
36
37#include <opm/input/eclipse/EclipseState/Grid/FaceDir.hpp>
38
39#include <opm/material/fluidstates/BlackOilFluidState.hpp>
40#include <opm/material/common/Valgrind.hpp>
41
49
51
52#include <opm/utility/CopyablePtr.hpp>
53
54#include <array>
55#include <cassert>
56#include <cstring>
57#include <limits>
58#include <stdexcept>
59#include <utility>
60
61namespace Opm {
62
70template <class TypeTag>
72 : public GetPropType<TypeTag, Properties::DiscIntensiveQuantities>
73 , public GetPropType<TypeTag, Properties::FluxModule>::FluxIntensiveQuantities
74 , public BlackOilDiffusionIntensiveQuantities<TypeTag, getPropValue<TypeTag, Properties::EnableDiffusion>() >
75 , public BlackOilDispersionIntensiveQuantities<TypeTag, getPropValue<TypeTag, Properties::EnableDispersion>() >
76 , public BlackOilSolventIntensiveQuantities<TypeTag, getPropValue<TypeTag, Properties::EnableSolvent>()>
77 , public BlackOilExtboIntensiveQuantities<TypeTag, getPropValue<TypeTag, Properties::EnableExtbo>()>
78 , public BlackOilPolymerIntensiveQuantities<TypeTag, getPropValue<TypeTag, Properties::EnablePolymer>()>
79 , public BlackOilFoamIntensiveQuantities<TypeTag, getPropValue<TypeTag, Properties::EnableFoam>()>
80 , public BlackOilBrineIntensiveQuantities<TypeTag, getPropValue<TypeTag, Properties::EnableBrine>()>
81 , public BlackOilEnergyIntensiveQuantities<TypeTag, getPropValue<TypeTag, Properties::EnergyModuleType>()>
82 , public BlackOilBioeffectsIntensiveQuantities<TypeTag, getPropValue<TypeTag, Properties::EnableBioeffects>()>
83 , public BlackOilConvectiveMixingIntensiveQuantities<TypeTag, getPropValue<TypeTag, Properties::EnableConvectiveMixing>()>
84{
87
96
97 enum { enableVapwat = getPropValue<TypeTag, Properties::EnableVapwat>() };
98 enum { enableDisgasInWater = getPropValue<TypeTag, Properties::EnableDisgasInWater>() };
99 enum { enableSaltPrecipitation = getPropValue<TypeTag, Properties::EnableSaltPrecipitation>() };
100 static constexpr EnergyModules energyModuleType = getPropValue<TypeTag, Properties::EnergyModuleType>();
101
102 static constexpr bool enableBioeffects = getPropValue<TypeTag, Properties::EnableBioeffects>();
103 static constexpr bool enableBrine = getPropValue<TypeTag, Properties::EnableBrine>();
104 static constexpr bool enableConvectiveMixing = getPropValue<TypeTag, Properties::EnableConvectiveMixing>();
105 static constexpr bool enableDiffusion = getPropValue<TypeTag, Properties::EnableDiffusion>();
106 static constexpr bool enableDispersion = getPropValue<TypeTag, Properties::EnableDispersion>();
107 static constexpr bool enableExtbo = getPropValue<TypeTag, Properties::EnableExtbo>();
108 static constexpr bool enableFoam = getPropValue<TypeTag, Properties::EnableFoam>();
109 static constexpr bool enablePolymer = getPropValue<TypeTag, Properties::EnablePolymer>();
110 static constexpr bool enableSolvent = getPropValue<TypeTag, Properties::EnableSolvent>();
111 static constexpr bool enableTemperature = energyModuleType != EnergyModules::NoTemperature;
112
113 enum { enableMech = getPropValue<TypeTag, Properties::EnableMech>() };
114 enum { enableMICP = Indices::enableMICP };
115 enum { numPhases = getPropValue<TypeTag, Properties::NumPhases>() };
116 enum { waterCompIdx = FluidSystem::waterCompIdx };
117 enum { oilCompIdx = FluidSystem::oilCompIdx };
118 enum { gasCompIdx = FluidSystem::gasCompIdx };
119 enum { waterPhaseIdx = FluidSystem::waterPhaseIdx };
120 enum { oilPhaseIdx = FluidSystem::oilPhaseIdx };
121 enum { gasPhaseIdx = FluidSystem::gasPhaseIdx };
122 static constexpr unsigned compositionSwitchIdx = Indices::compositionSwitchIdx;
123
124 static constexpr bool compositionSwitchEnabled =
125 Indices::compositionSwitchIdx != std::numeric_limits<unsigned>::max();
126 static constexpr bool waterEnabled = Indices::waterEnabled;
127 static constexpr bool gasEnabled = Indices::gasEnabled;
128 static constexpr bool oilEnabled = Indices::oilEnabled;
129
130 using Toolbox = MathToolbox<Evaluation>;
131 using FluxIntensiveQuantities = typename FluxModule::FluxIntensiveQuantities;
134
135 using DirectionalMobilityPtr = Utility::CopyablePtr<DirectionalMobility<TypeTag>>;
136 using BrineModule = BlackOilBrineModule<TypeTag, enableBrine>;
138 using BioeffectsModule = BlackOilBioeffectsModule<TypeTag, enableBioeffects>;
140
141public:
142 using FluidState = BlackOilFluidState<Evaluation,
143 FluidSystem,
144 energyModuleType != EnergyModules::NoTemperature,
145 energyModuleType == EnergyModules::FullyImplicitThermal,
146 compositionSwitchEnabled,
147 enableVapwat,
148 enableBrine,
149 enableSaltPrecipitation,
150 enableDisgasInWater,
151 enableSolvent,
152 Indices::numPhases>;
153 using ScalarFluidState = BlackOilFluidState<Scalar,
154 FluidSystem,
155 energyModuleType != EnergyModules::NoTemperature,
156 energyModuleType == EnergyModules::FullyImplicitThermal,
157 compositionSwitchEnabled,
158 enableVapwat,
159 enableBrine,
160 enableSaltPrecipitation,
161 enableDisgasInWater,
162 enableSolvent,
163 Indices::numPhases>;
165
167 {
168 if constexpr (compositionSwitchEnabled) {
169 fluidState_.setRs(0.0);
170 fluidState_.setRv(0.0);
171 }
172 if constexpr (enableVapwat) {
173 fluidState_.setRvw(0.0);
174 }
175 if constexpr (enableDisgasInWater) {
176 fluidState_.setRsw(0.0);
177 }
178 }
179
180 OPM_HOST_DEVICE BlackOilIntensiveQuantities& operator=(const BlackOilIntensiveQuantities& other) = default;
181
182 template<class OtherTypeTag>
184
185 // This ctor is used when switching to the GPU typetag which currently supports thermal effects and diffusion.
186 template<class OtherTypeTag>
188 const BlackOilIntensiveQuantities<OtherTypeTag>& other, const FluidSystem& fsystem)
189 : fluidState_(other.fluidState_.template withOtherFluidSystem<FluidSystem>(fsystem))
190 , BlackOilEnergyIntensiveQuantities<TypeTag, energyModuleType>(other)
192 , referencePorosity_(other.referencePorosity_)
193 , porosity_(other.porosity_)
194 , rockCompTransMultiplier_(other.rockCompTransMultiplier_)
195 , mobility_(other.mobility_)
196 , dirMob_(/*NOT YET SUPPORTED ON GPU*/)
197 {
198 }
199
201
210 template <class OtherTypeTag>
212 {
213 BlackOilIntensiveQuantities<OtherTypeTag> newIntQuants(*this, other);
214 return newIntQuants;
215 }
216
225 template<class OtherTypeTag>
228 {
229 fluidState_.assign(other.fluidState_);
230
231 if constexpr (energyModuleType == EnergyModules::FullyImplicitThermal) {
232 this->rockInternalEnergy_ = other.rockInternalEnergy_;
233 this->totalThermalConductivity_ = other.totalThermalConductivity_;
234 this->rockFraction_ = other.rockFraction_;
235 }
236 porosity_ = other.porosity_;
237 referencePorosity_ = other.referencePorosity_;
238 rockCompTransMultiplier_ = other.rockCompTransMultiplier_;
239 mobility_ = other.mobility_;
240 this->extrusionFactor_ = other.extrusionFactor();
241 }
242
243 OPM_HOST_DEVICE void updateTempSalt(const Problem& problem,
244 const PrimaryVariables& priVars,
245 const unsigned globalSpaceIdx,
246 const unsigned timeIdx,
247 const LinearizationType& lintype)
248 {
249 if constexpr (enableTemperature) {
250 asImp_().updateTemperature_(problem, priVars, globalSpaceIdx, timeIdx, lintype);
251 }
252 if constexpr (enableBrine) {
253 asImp_().updateSaltConcentration_(priVars, timeIdx, lintype);
254 }
255 }
256
257 OPM_HOST_DEVICE void updateSaturations(const PrimaryVariables& priVars,
258 const unsigned timeIdx,
259 [[maybe_unused]] const LinearizationType lintype)
260 {
261 // extract the water and the gas saturations for convenience
262 Evaluation Sw = 0.0;
263 if constexpr (waterEnabled) {
264 if (priVars.primaryVarsMeaningWater() == PrimaryVariables::WaterMeaning::Sw) {
265 assert(Indices::waterSwitchIdx != std::numeric_limits<unsigned>::max());
266 if constexpr (Indices::waterSwitchIdx != std::numeric_limits<unsigned>::max()) {
267 Sw = priVars.makeEvaluation(Indices::waterSwitchIdx, timeIdx);
268 }
269 }
270 else if (priVars.primaryVarsMeaningWater() == PrimaryVariables::WaterMeaning::Rsw ||
271 priVars.primaryVarsMeaningWater() == PrimaryVariables::WaterMeaning::Disabled)
272 {
273 // water is enabled but is not a primary variable i.e. one component/phase case
274 // or two-phase water + gas with only water present
275 Sw = 1.0;
276 } // else i.e. for MeaningWater() = Rvw, Sw is still 0.0;
277 }
278 Evaluation Sg = 0.0;
279 if constexpr (gasEnabled) {
280 if (priVars.primaryVarsMeaningGas() == PrimaryVariables::GasMeaning::Sg) {
281 assert(Indices::compositionSwitchIdx != std::numeric_limits<unsigned>::max());
282 if constexpr (compositionSwitchEnabled) {
283 Sg = priVars.makeEvaluation(Indices::compositionSwitchIdx, timeIdx);
284 }
285 }
286 else if (priVars.primaryVarsMeaningGas() == PrimaryVariables::GasMeaning::Rv) {
287 Sg = 1.0 - Sw;
288 }
289 else if (priVars.primaryVarsMeaningGas() == PrimaryVariables::GasMeaning::Disabled) {
290 if constexpr (waterEnabled) {
291 Sg = 1.0 - Sw; // two phase water + gas
292 } else {
293 // one phase case
294 Sg = 1.0;
295 }
296 }
297 }
298 Valgrind::CheckDefined(Sg);
299 Valgrind::CheckDefined(Sw);
300
301 Evaluation So = 1.0 - Sw - Sg;
302
303 // deal with solvent
304 if constexpr (enableSolvent) {
305 if (priVars.primaryVarsMeaningSolvent() == PrimaryVariables::SolventMeaning::Ss) {
306 if (getFluidSystem().phaseIsActive(oilPhaseIdx)) {
307 So -= priVars.makeEvaluation(Indices::solventSaturationIdx, timeIdx);
308 }
309 else if (getFluidSystem().phaseIsActive(gasPhaseIdx)) {
310 Sg -= priVars.makeEvaluation(Indices::solventSaturationIdx, timeIdx);
311 }
312 }
313 }
314
315 if (getFluidSystem().phaseIsActive(waterPhaseIdx)) {
316 fluidState_.setSaturation(waterPhaseIdx, Sw);
317 }
318
319 if (getFluidSystem().phaseIsActive(gasPhaseIdx)) {
320 fluidState_.setSaturation(gasPhaseIdx, Sg);
321 }
322
323 if (getFluidSystem().phaseIsActive(oilPhaseIdx)) {
324 fluidState_.setSaturation(oilPhaseIdx, So);
325 }
326 }
327
328 template <class ...Args>
329 OPM_HOST_DEVICE void updateRelpermAndPressures(const Problem& problem,
330 const PrimaryVariables& priVars,
331 const unsigned globalSpaceIdx,
332 const unsigned timeIdx,
333 const LinearizationType& lintype)
334 {
335
336 // Solvent saturation manipulation:
337 // After this, gas saturation will actually be (gas sat + solvent sat)
338 // until set back to just gas saturation in the corresponding call to
339 // solventPostSatFuncUpdate_() further down.
340 if constexpr (enableSolvent) {
341 asImp_().solventPreSatFuncUpdate_(priVars, timeIdx, lintype);
342 }
343
344 // Phase relperms.
345 problem.template updateRelperms<FluidState, Args...>(mobility_, dirMob_, fluidState_, globalSpaceIdx);
346
347 // now we compute all phase pressures
348 using EvalArr = std::array<Evaluation, numPhases>;
349 EvalArr pC;
350 const auto& materialParams = problem.materialLawParams(globalSpaceIdx);
351 MaterialLaw::template capillaryPressures<EvalArr, FluidState, Args...>(pC, materialParams, fluidState_);
352
353 // scaling the capillary pressure due to porosity changes
354 if constexpr (enableBrine) {
355 if (BrineModule::hasPcfactTables() &&
356 priVars.primaryVarsMeaningBrine() == PrimaryVariables::BrineMeaning::Sp)
357 {
358 const unsigned satnumRegionIdx = problem.satnumRegionIndex(globalSpaceIdx);
359 const Evaluation Sp = priVars.makeEvaluation(Indices::saltConcentrationIdx, timeIdx);
360 const Evaluation porosityFactor = min(1.0 - Sp, 1.0); //phi/phi_0
361 const auto& pcfactTable = BrineModule::pcfactTable(satnumRegionIdx);
362 const Evaluation pcFactor = pcfactTable.eval(porosityFactor, /*extrapolation=*/true);
363 for (unsigned phaseIdx = 0; phaseIdx < numPhases; ++phaseIdx) {
364 if (getFluidSystem().phaseIsActive(phaseIdx)) {
365 pC[phaseIdx] *= pcFactor;
366 }
367 }
368 }
369 }
370 else if constexpr (enableBioeffects) {
371 if (BioeffectsModule::hasPcfactTables() && referencePorosity_ > 0) {
372 unsigned satnumRegionIdx = problem.satnumRegionIndex(globalSpaceIdx);
373 const Evaluation Sb = priVars.makeEvaluation(Indices::biofilmVolumeFractionIdx, timeIdx);
374 const Evaluation porosityFactor = min(1.0 - Sb/referencePorosity_, 1.0); //phi/phi_0
375 const auto& pcfactTable = BioeffectsModule::pcfactTable(satnumRegionIdx);
376 const Evaluation pcFactor = pcfactTable.eval(porosityFactor, /*extrapolation=*/true);
377 for (unsigned phaseIdx = 0; phaseIdx < numPhases; ++phaseIdx) {
378 if (getFluidSystem().phaseIsActive(phaseIdx)) {
379 pC[phaseIdx] *= pcFactor;
380 }
381 }
382 }
383 }
384
385 // oil is the reference phase for pressure
386 if (priVars.primaryVarsMeaningPressure() == PrimaryVariables::PressureMeaning::Pg) {
387 const Evaluation& pg = priVars.makeEvaluation(Indices::pressureSwitchIdx, timeIdx);
388 for (unsigned phaseIdx = 0; phaseIdx < numPhases; ++phaseIdx) {
389 if (getFluidSystem().phaseIsActive(phaseIdx)) {
390 fluidState_.setPressure(phaseIdx, pg + (pC[phaseIdx] - pC[gasPhaseIdx]));
391 }
392 }
393 }
394 else if (priVars.primaryVarsMeaningPressure() == PrimaryVariables::PressureMeaning::Pw) {
395 const Evaluation& pw = priVars.makeEvaluation(Indices::pressureSwitchIdx, timeIdx);
396 for (unsigned phaseIdx = 0; phaseIdx < numPhases; ++phaseIdx) {
397 if (getFluidSystem().phaseIsActive(phaseIdx)) {
398 fluidState_.setPressure(phaseIdx, pw + (pC[phaseIdx] - pC[waterPhaseIdx]));
399 }
400 }
401 }
402 else {
403 assert(getFluidSystem().phaseIsActive(oilPhaseIdx));
404 const Evaluation& po = priVars.makeEvaluation(Indices::pressureSwitchIdx, timeIdx);
405 for (unsigned phaseIdx = 0; phaseIdx < numPhases; ++phaseIdx) {
406 if (getFluidSystem().phaseIsActive(phaseIdx)) {
407 fluidState_.setPressure(phaseIdx, po + (pC[phaseIdx] - pC[oilPhaseIdx]));
408 }
409 }
410 }
411
412 // Update the Saturation functions for the blackoil solvent module.
413 // Including setting gas saturation back to hydrocarbon gas saturation.
414 // Note that this depend on the pressures, so it must be called AFTER the pressures
415 // have been updated.
416 if constexpr (enableSolvent) {
417 asImp_().solventPostSatFuncUpdate_(problem, priVars, globalSpaceIdx, timeIdx, lintype);
418 }
419 }
420
421 OPM_HOST_DEVICE void updateRsRvRsw(const Problem& problem,
422 const PrimaryVariables& priVars,
423 const unsigned globalSpaceIdx,
424 const unsigned timeIdx)
425 {
426 const unsigned pvtRegionIdx = priVars.pvtRegionIndex();
427
428 const Scalar RvMax = getFluidSystem().enableVaporizedOil()
429 ? problem.maxOilVaporizationFactor(timeIdx, globalSpaceIdx)
430 : 0.0;
431 const Scalar RsMax = getFluidSystem().enableDissolvedGas()
432 ? problem.maxGasDissolutionFactor(timeIdx, globalSpaceIdx)
433 : 0.0;
434 const Scalar RswMax = getFluidSystem().enableDissolvedGasInWater()
435 ? problem.maxGasDissolutionFactor(timeIdx, globalSpaceIdx)
436 : 0.0;
437
438 Evaluation SoMax = 0.0;
439 if (getFluidSystem().phaseIsActive(getFluidSystem().oilPhaseIdx)) {
440 SoMax = max(fluidState_.saturation(oilPhaseIdx),
441 problem.maxOilSaturation(globalSpaceIdx));
442 }
443
444 // take the meaning of the switching primary variable into account for the gas
445 // and oil phase compositions
446
447 if constexpr (compositionSwitchEnabled) {
448 if (priVars.primaryVarsMeaningGas() == PrimaryVariables::GasMeaning::Rs) {
449 const auto& Rs = priVars.makeEvaluation(Indices::compositionSwitchIdx, timeIdx);
450 fluidState_.setRs(Rs);
451 }
452 else {
453 if (getFluidSystem().enableDissolvedGas()) { // Add So > 0? i.e. if only water set rs = 0)
454 Evaluation RsSat;
455 if constexpr (enableExtbo) {
456 RsSat = asImp_().rs();
457 } else {
458 RsSat = getFluidSystem().saturatedDissolutionFactor(fluidState_,
459 oilPhaseIdx,
460 pvtRegionIdx,
461 SoMax);
462 }
463 fluidState_.setRs(min(RsMax, RsSat));
464 }
465 else {
466 fluidState_.setRs(0.0);
467 }
468 }
469
470 if (priVars.primaryVarsMeaningGas() == PrimaryVariables::GasMeaning::Rv) {
471 const auto& Rv = priVars.makeEvaluation(Indices::compositionSwitchIdx, timeIdx);
472 fluidState_.setRv(Rv);
473 }
474 else {
475 if (getFluidSystem().enableVaporizedOil() ) { // Add Sg > 0? i.e. if only water set rv = 0)
476 Evaluation RvSat;
477 if constexpr (enableExtbo) {
478 RvSat = asImp_().rv();
479 } else {
480 RvSat = getFluidSystem().saturatedDissolutionFactor(fluidState_,
481 gasPhaseIdx,
482 pvtRegionIdx,
483 SoMax);
484 }
485 fluidState_.setRv(min(RvMax, RvSat));
486 }
487 else {
488 fluidState_.setRv(0.0);
489 }
490 }
491 }
492
493 if constexpr (enableVapwat) {
494 if (priVars.primaryVarsMeaningWater() == PrimaryVariables::WaterMeaning::Rvw) {
495 const auto& Rvw = priVars.makeEvaluation(Indices::waterSwitchIdx, timeIdx);
496 fluidState_.setRvw(Rvw);
497 }
498 else {
499 if (getFluidSystem().enableVaporizedWater()) { // Add Sg > 0? i.e. if only water set rv = 0)
500 const Evaluation& RvwSat = getFluidSystem().saturatedVaporizationFactor(fluidState_,
501 gasPhaseIdx,
502 pvtRegionIdx);
503 fluidState_.setRvw(RvwSat);
504 }
505 }
506 }
507
508 if constexpr (enableDisgasInWater) {
509 if (priVars.primaryVarsMeaningWater() == PrimaryVariables::WaterMeaning::Rsw) {
510 const auto& Rsw = priVars.makeEvaluation(Indices::waterSwitchIdx, timeIdx);
511 fluidState_.setRsw(Rsw);
512 }
513 else {
514 if (getFluidSystem().enableDissolvedGasInWater()) {
515 const Evaluation& RswSat = getFluidSystem().saturatedDissolutionFactor(fluidState_,
516 waterPhaseIdx,
517 pvtRegionIdx);
518 fluidState_.setRsw(min(RswMax, RswSat));
519 }
520 }
521 }
522 }
523
524 OPM_HOST_DEVICE void updateMobilityAndInvB()
525 {
526 OPM_TIMEBLOCK_LOCAL(updateMobilityAndInvB, Subsystem::PvtProps);
527 const unsigned pvtRegionIdx = fluidState_.pvtRegionIndex();
528
529 // compute the phase densities and transform the phase permeabilities into mobilities
530 int nmobilities = 1;
531 constexpr int max_nmobilities = 4;
532 std::array<std::array<Evaluation, numPhases>*, max_nmobilities> mobilities = { &mobility_};
533 if (dirMob_) {
534 for (int i = 0; i < 3; ++i) {
535 mobilities[nmobilities] = &(dirMob_->getArray(i));
536 ++nmobilities;
537 }
538 }
539 for (unsigned phaseIdx = 0; phaseIdx < numPhases; ++phaseIdx) {
540 if (!getFluidSystem().phaseIsActive(phaseIdx)) {
541 continue;
542 }
543 const auto [b, mu] = getFluidSystem().inverseFormationVolumeFactorAndViscosity(fluidState_, phaseIdx, pvtRegionIdx);
544 fluidState_.setInvB(phaseIdx, b);
545 for (int i = 0; i < nmobilities; ++i) {
546 if constexpr (enableExtbo) {
547 if (phaseIdx == oilPhaseIdx) {
548 (*mobilities[i])[phaseIdx] /= asImp_().oilViscosity();
549 }
550 else if (phaseIdx == gasPhaseIdx) {
551 (*mobilities[i])[phaseIdx] /= asImp_().gasViscosity();
552 }
553 else {
554 (*mobilities[i])[phaseIdx] /= mu;
555 }
556 }
557 else {
558 (*mobilities[i])[phaseIdx] /= mu;
559 }
560 }
561 }
562 Valgrind::CheckDefined(mobility_);
563 }
564
565 OPM_HOST_DEVICE void updatePhaseDensities()
566 {
567 const unsigned pvtRegionIdx = fluidState_.pvtRegionIndex();
568
569 // calculate the phase densities
570 Evaluation rho;
571 if (getFluidSystem().phaseIsActive(waterPhaseIdx)) {
572 rho = fluidState_.invB(waterPhaseIdx);
573 rho *= getFluidSystem().referenceDensity(waterPhaseIdx, pvtRegionIdx);
574 if (getFluidSystem().enableDissolvedGasInWater()) {
575 rho += fluidState_.invB(waterPhaseIdx) *
576 fluidState_.Rsw() *
577 getFluidSystem().referenceDensity(gasPhaseIdx, pvtRegionIdx);
578 }
579 fluidState_.setDensity(waterPhaseIdx, rho);
580 }
581
582 if (getFluidSystem().phaseIsActive(gasPhaseIdx)) {
583 rho = fluidState_.invB(gasPhaseIdx);
584 rho *= getFluidSystem().referenceDensity(gasPhaseIdx, pvtRegionIdx);
585 if (getFluidSystem().enableVaporizedOil()) {
586 rho += fluidState_.invB(gasPhaseIdx) *
587 fluidState_.Rv() *
588 getFluidSystem().referenceDensity(oilPhaseIdx, pvtRegionIdx);
589 }
590 if (getFluidSystem().enableVaporizedWater()) {
591 rho += fluidState_.invB(gasPhaseIdx) *
592 fluidState_.Rvw() *
593 getFluidSystem().referenceDensity(waterPhaseIdx, pvtRegionIdx);
594 }
595 fluidState_.setDensity(gasPhaseIdx, rho);
596 }
597
598 if (getFluidSystem().phaseIsActive(oilPhaseIdx)) {
599 rho = fluidState_.invB(oilPhaseIdx);
600 rho *= getFluidSystem().referenceDensity(oilPhaseIdx, pvtRegionIdx);
601 if (getFluidSystem().enableDissolvedGas()) {
602 rho += fluidState_.invB(oilPhaseIdx) *
603 fluidState_.Rs() *
604 getFluidSystem().referenceDensity(gasPhaseIdx, pvtRegionIdx);
605 }
606 fluidState_.setDensity(oilPhaseIdx, rho);
607 }
608 }
609
610 OPM_HOST_DEVICE void updatePorosity(const ElementContext& elemCtx, unsigned dofIdx, unsigned timeIdx)
611 {
612 const auto& problem = elemCtx.problem();
613 const auto& priVars = elemCtx.primaryVars(dofIdx, timeIdx);
614 const unsigned globalSpaceIdx = elemCtx.globalSpaceIndex(dofIdx, timeIdx);
615 // Retrieve the reference porosity from the problem.
616 referencePorosity_ = problem.porosity(elemCtx, dofIdx, timeIdx);
617 // Account for other effects.
618 this->updatePorosityImpl(problem, priVars, globalSpaceIdx, timeIdx);
619 }
620
621 OPM_HOST_DEVICE void updatePorosity(const Problem& problem,
622 const PrimaryVariables& priVars,
623 const unsigned globalSpaceIdx,
624 const unsigned timeIdx)
625 {
626 // Retrieve the reference porosity from the problem.
627 referencePorosity_ = problem.porosity(globalSpaceIdx, timeIdx);
628 // Account for other effects.
629 this->updatePorosityImpl(problem, priVars, globalSpaceIdx, timeIdx);
630 }
631
632 OPM_HOST_DEVICE void updatePorosityImpl(const Problem& problem,
633 const PrimaryVariables& priVars,
634 const unsigned globalSpaceIdx,
635 const unsigned timeIdx)
636 {
637 const auto& linearizationType = problem.model().linearizer().getLinearizationType();
638
639 // Start from the reference porosity.
640 porosity_ = referencePorosity_;
641
642 // the porosity must be modified by the compressibility of the
643 // rock...
644 const Scalar rockCompressibility = problem.rockCompressibility(globalSpaceIdx);
645 if (rockCompressibility > 0.0) {
646 const Scalar rockRefPressure = problem.rockReferencePressure(globalSpaceIdx);
647 Evaluation x;
648 if (getFluidSystem().phaseIsActive(oilPhaseIdx)) {
649 x = rockCompressibility * (fluidState_.pressure(oilPhaseIdx) - rockRefPressure);
650 }
651 else if (getFluidSystem().phaseIsActive(waterPhaseIdx)) {
652 x = rockCompressibility * (fluidState_.pressure(waterPhaseIdx) - rockRefPressure);
653 }
654 else {
655 x = rockCompressibility * (fluidState_.pressure(gasPhaseIdx) - rockRefPressure);
656 }
657 porosity_ *= 1.0 + x + 0.5 * x * x;
658 }
659
660 // deal with water induced rock compaction
661 porosity_ *= problem.template rockCompPoroMultiplier<Evaluation>(*this, globalSpaceIdx);
662
663 // deal with bioeffects (minimum porosity of 1e-8 to prevent numerical issues)
664 if constexpr (enableBioeffects) {
665 const Evaluation biofilm_ = priVars.makeEvaluation(Indices::biofilmVolumeFractionIdx,
666 timeIdx, linearizationType);
667 Evaluation calcite_ = 0.0;
668 if constexpr (enableMICP) {
669 calcite_ = priVars.makeEvaluation(Indices::calciteVolumeFractionIdx, timeIdx, linearizationType);
670 }
671 porosity_ -= min(biofilm_ + calcite_, referencePorosity_ - 1e-8);
672 }
673
674 // deal with salt-precipitation
675 if (enableSaltPrecipitation && priVars.primaryVarsMeaningBrine() == PrimaryVariables::BrineMeaning::Sp) {
676 const Evaluation Sp = priVars.makeEvaluation(Indices::saltConcentrationIdx, timeIdx);
677 porosity_ *= (1.0 - Sp);
678 }
679
680
681 // Geomechanical updates to porosity/pore volume
682 if constexpr (enableMech) {
683 // TPSA calculations
684 if (problem.simulator().vanguard().eclState().runspec().mechSolver().tpsa()) {
685 // TPSA compressibility term
686 const Scalar rockBiot = problem.rockBiotComp(globalSpaceIdx);
687 if (rockBiot > 0.0) {
688 const Scalar rockRefPressure = problem.rockReferencePressure(globalSpaceIdx);
689 Evaluation active_pressure;
690 if (FluidSystem::phaseIsActive(oilPhaseIdx)) {
691 active_pressure = fluidState_.pressure(oilPhaseIdx) - rockRefPressure;
692 } else if (FluidSystem::phaseIsActive(waterPhaseIdx)){
693 active_pressure = fluidState_.pressure(waterPhaseIdx) - rockRefPressure;
694 } else {
695 active_pressure = fluidState_.pressure(gasPhaseIdx) - rockRefPressure;
696 }
697 porosity_ += rockBiot * active_pressure;
698 }
699
700 if constexpr (energyModuleType == EnergyModules::FullyImplicitThermal) {
701 const Scalar rockBiotTemp = problem.rockBiotTemp(globalSpaceIdx);
702 if (rockBiotTemp != 0.0) {
703 const Scalar rockRefTemp = problem.rockReferenceTemperature();
704 Evaluation active_temp = fluidState_.temperature(/*phaseIdx=*/0) -
705 rockRefTemp;
706 porosity_ += rockBiotTemp * active_temp;
707 }
708 }
709
710 // TPSA coupling term, pore volume changes due to mechanics
711 porosity_ += problem.rockMechPoroChange(globalSpaceIdx, /*timeIdx=*/timeIdx);
712 }
713 }
714 }
715
716 OPM_HOST_DEVICE void assertFiniteMembers()
717 {
718 // some safety checks in debug mode
719 for (unsigned phaseIdx = 0; phaseIdx < numPhases; ++phaseIdx) {
720 if (!getFluidSystem().phaseIsActive(phaseIdx)) {
721 continue;
722 }
723
724 assert(isfinite(fluidState_.density(phaseIdx)));
725 assert(isfinite(fluidState_.saturation(phaseIdx)));
726 assert(isfinite(fluidState_.temperature(phaseIdx)));
727 assert(isfinite(fluidState_.pressure(phaseIdx)));
728 assert(isfinite(fluidState_.invB(phaseIdx)));
729 }
730 assert(isfinite(fluidState_.Rs()));
731 assert(isfinite(fluidState_.Rv()));
732 }
733
737 template <class ...Args>
738 OPM_HOST_DEVICE void update(const ElementContext& elemCtx, unsigned dofIdx, unsigned timeIdx)
739 {
740 ParentType::update(elemCtx, dofIdx, timeIdx);
741 const auto& problem = elemCtx.problem();
742 const auto& priVars = elemCtx.primaryVars(dofIdx, timeIdx);
743 const unsigned globalSpaceIdx = elemCtx.globalSpaceIndex(dofIdx, timeIdx);
744
745 updateCommonPart<Args...>(problem, priVars, globalSpaceIdx, timeIdx);
746
747 updatePorosity(elemCtx, dofIdx, timeIdx);
748
749 // Below: things I want to move to elemCtx-less versions but have not done yet.
750
751 if constexpr (enableSolvent) {
752 asImp_().solventPvtUpdate_(elemCtx, dofIdx, timeIdx);
753 }
754 if constexpr (enableExtbo) {
755 asImp_().zPvtUpdate_();
756 }
757 if constexpr (enablePolymer) {
758 asImp_().polymerPropertiesUpdate_(elemCtx, dofIdx, timeIdx);
759 }
760 if constexpr (energyModuleType == EnergyModules::FullyImplicitThermal) {
761 asImp_().updateEnergyQuantities_(elemCtx, dofIdx, timeIdx);
762 }
763 if constexpr (enableFoam) {
764 asImp_().foamPropertiesUpdate_(elemCtx, dofIdx, timeIdx);
765 }
766 if constexpr (enableBioeffects) {
767 asImp_().bioeffectsPropertiesUpdate_(elemCtx, dofIdx, timeIdx);
768 }
769 if constexpr (enableBrine) {
770 asImp_().saltPropertiesUpdate_(elemCtx, dofIdx, timeIdx);
771 }
772 if constexpr (enableConvectiveMixing) {
773 // The ifs are here is to avoid extra calculations for
774 // cases with dry runs and without CO2STORE and DRSDTCON.
775 if (!problem.simulator().vanguard().eclState().getIOConfig().initOnly()) {
776 if (problem.simulator().vanguard().eclState().runspec().co2Storage()) {
777 if (problem.drsdtconIsActive(globalSpaceIdx, problem.simulator().episodeIndex())) {
778 asImp_().updateSaturatedDissolutionFactor_();
779 }
780 }
781 }
782 }
783
784 // update the quantities which are required by the chosen
785 // velocity model
786 FluxIntensiveQuantities::update_(elemCtx, dofIdx, timeIdx);
787
788 // update the diffusion specific quantities of the intensive quantities
789 if constexpr (enableDiffusion) {
790 DiffusionIntensiveQuantities::update_(fluidState_, priVars.pvtRegionIndex(), elemCtx, dofIdx, timeIdx);
791 }
792
793 // update the dispersion specific quantities of the intensive quantities
794 if constexpr (enableDispersion) {
795 DispersionIntensiveQuantities::update_(elemCtx, dofIdx, timeIdx);
796 }
797 }
798
799 template <class ...Args>
800 OPM_HOST_DEVICE void update(const Problem& problem,
801 const PrimaryVariables& priVars,
802 const unsigned globalSpaceIdx,
803 const unsigned timeIdx)
804 {
805 // This is the version of update() that does not use any ElementContext.
806 // It is limited by some modules that are not yet adapted to that.
807 static_assert(!enableSolvent);
808 static_assert(!enableExtbo);
809 static_assert(!enablePolymer);
810 static_assert(!enableFoam);
811 static_assert(!enableMICP);
812 static_assert(!enableBrine);
813 static_assert(!enableDiffusion);
814 static_assert(!enableDispersion);
815
816 this->extrusionFactor_ = 1.0;// to avoid fixing parent update
817 updateCommonPart<Args...>(problem, priVars, globalSpaceIdx, timeIdx);
818 // Porosity requires separate calls so this can be instantiated with ReservoirProblem from the examples/ directory.
819 updatePorosity(problem, priVars, globalSpaceIdx, timeIdx);
820
821 // TODO: Here we should do the parts for solvent etc. at the bottom of the other update() function.
822 }
823
824 // This function updated the parts that are common to the IntensiveQuantities regardless of extensions used.
825 template <class ...Args>
826 OPM_HOST_DEVICE void updateCommonPart(const Problem& problem,
827 const PrimaryVariables& priVars,
828 const unsigned globalSpaceIdx,
829 const unsigned timeIdx)
830 {
831 OPM_TIMEBLOCK_LOCAL(blackoilIntensiveQuanititiesUpdate, Subsystem::SatProps | Subsystem::PvtProps);
832
833 const auto& linearizationType = problem.model().linearizer().getLinearizationType();
834 const unsigned pvtRegionIdx = priVars.pvtRegionIndex();
835
836 fluidState_.setPvtRegionIndex(pvtRegionIdx);
837
838 updateTempSalt(problem, priVars, globalSpaceIdx, timeIdx, linearizationType);
839 updateSaturations(priVars, timeIdx, linearizationType);
840 updateRelpermAndPressures<Args...>(problem, priVars, globalSpaceIdx, timeIdx, linearizationType);
841
842 // update extBO parameters
843 if constexpr (enableExtbo) {
844 asImp_().zFractionUpdate_(priVars, timeIdx);
845 }
846
847 updateRsRvRsw(problem, priVars, globalSpaceIdx, timeIdx);
850
851 rockCompTransMultiplier_ = problem.template rockCompTransMultiplier<Evaluation>(*this, globalSpaceIdx);
852
853#ifndef NDEBUG
855#endif
856 }
857
861 OPM_HOST_DEVICE const FluidState& fluidState() const
862 { return fluidState_; }
863
864 // non-const version
865 OPM_HOST_DEVICE FluidState& fluidState()
866 { return fluidState_; }
867
871 OPM_HOST_DEVICE const Evaluation& mobility(unsigned phaseIdx) const
872 { return mobility_[phaseIdx]; }
873
874 OPM_HOST_DEVICE const Evaluation& mobility(unsigned phaseIdx, FaceDir::DirEnum facedir) const
875 {
876 using Dir = FaceDir::DirEnum;
877 if (dirMob_) {
878 bool constexpr usesStaticFluidSystem = std::is_empty_v<FluidSystem>;
879 if constexpr (usesStaticFluidSystem)
880 {
881 switch (facedir) {
882 case Dir::XMinus:
883 case Dir::XPlus:
884 return dirMob_->getArray(0)[phaseIdx];
885 case Dir::YMinus:
886 case Dir::YPlus:
887 return dirMob_->getArray(1)[phaseIdx];
888 case Dir::ZMinus:
889 case Dir::ZPlus:
890 return dirMob_->getArray(2)[phaseIdx];
891 default:
892 OPM_THROW(std::runtime_error, "Unexpected face direction");
893 }
894 }
895 else{
896 OPM_THROW(std::logic_error, "Directional mobility with non-static fluid system is not supported yet");
897 }
898 }
899 else {
900 return mobility_[phaseIdx];
901 }
902 }
903
907 OPM_HOST_DEVICE const Evaluation& porosity() const
908 { return porosity_; }
909
913 OPM_HOST_DEVICE const Evaluation& rockCompTransMultiplier() const
914 { return rockCompTransMultiplier_; }
915
923 OPM_HOST_DEVICE auto pvtRegionIndex() const -> decltype(std::declval<FluidState>().pvtRegionIndex())
924 { return fluidState_.pvtRegionIndex(); }
925
929 OPM_HOST_DEVICE Evaluation relativePermeability(unsigned phaseIdx) const
930 {
931 // warning: slow
932 return fluidState_.viscosity(phaseIdx) * mobility(phaseIdx);
933 }
934
941 OPM_HOST_DEVICE Scalar referencePorosity() const
942 { return referencePorosity_; }
943
944 OPM_HOST_DEVICE const Evaluation& permFactor() const
945 {
946 if constexpr (enableBioeffects) {
947 return BioeffectsIntQua::permFactor();
948 }
949 else if constexpr (enableSaltPrecipitation) {
950 return BrineIntQua::permFactor();
951 }
952 else {
953 OPM_THROW(std::logic_error, "permFactor() called but salt precipitation and bioeffects are disabled");
954 }
955 }
956
960 OPM_HOST_DEVICE const auto& getFluidSystem() const
961 {
962 return fluidState_.fluidSystem();
963 }
964
965private:
973
974 OPM_HOST_DEVICE Implementation& asImp_()
975 { return *static_cast<Implementation*>(this); }
976
977 FluidState fluidState_;
978 Scalar referencePorosity_;
979 Evaluation porosity_;
980 Evaluation rockCompTransMultiplier_;
981 std::array<Evaluation, numPhases> mobility_;
982
983 // Instead of writing a custom copy constructor and a custom assignment operator just to handle
984 // the dirMob_ unique ptr member variable when copying BlackOilIntensiveQuantites (see for example
985 // updateIntensitiveQuantities_() in fvbaseelementcontext.hh for a copy example) we write the below
986 // custom wrapper class CopyablePtr which wraps the unique ptr and makes it copyable.
987 //
988 // The advantage of this approach is that we avoid having to call all the base class copy constructors and
989 // assignment operators explicitly (which is needed when writing the custom copy constructor and assignment
990 // operators) which could become a maintenance burden. For example, when adding a new base class (if that should
991 // be needed sometime in the future) to BlackOilIntensiveQuantites we could forget to update the copy
992 // constructor and assignment operators.
993 //
994 // We want each copy of the BlackOilIntensiveQuantites to be unique, (TODO: why?) so we have to make a copy
995 // of the unique_ptr each time we copy construct or assign to it from another BlackOilIntensiveQuantites.
996 // (On the other hand, if a copy could share the ptr with the original, a shared_ptr could be used instead and the
997 // wrapper would not be needed)
998 DirectionalMobilityPtr dirMob_;
999};
1000
1001} // namespace Opm
1002
1003#endif
Classes required for molecular diffusion.
Classes required for mechanical dispersion.
Contains the classes required to extend the black-oil model by energy.
Contains classes extending the black-oil model. \detail This file holds dummy definitions,...
Contains the classes required to extend the black-oil model by polymer.
Declares the properties required by the black oil model.
Provides the volumetric quantities required for the equations needed by the brine extension of the bl...
Provides the volumetric quantities required for the equations needed by the bioeffects extension of t...
Provides the volumetric quantities required for the equations needed by the convective mixing (DRSDTC...
Provides the volumetric quantities required for the calculation of molecular diffusive fluxes.
Provides the volumetric quantities required for the calculation of dispersive fluxes.
Provides the volumetric quantities required for the equations needed by the energys extension of the ...
Definition: blackoilmodules.hpp:68
Provides the volumetric quantities required for the equations needed by the solvents extension of the...
Provides the volumetric quantities required for the equations needed by the polymers extension of the...
Contains the quantities which are are constant within a finite volume in the black-oil model.
Definition: blackoilintensivequantities.hh:84
OPM_HOST_DEVICE void updatePorosityImpl(const Problem &problem, const PrimaryVariables &priVars, const unsigned globalSpaceIdx, const unsigned timeIdx)
Definition: blackoilintensivequantities.hh:632
OPM_HOST_DEVICE void update(const ElementContext &elemCtx, unsigned dofIdx, unsigned timeIdx)
Definition: blackoilintensivequantities.hh:738
OPM_HOST_DEVICE void updateSaturations(const PrimaryVariables &priVars, const unsigned timeIdx, const LinearizationType lintype)
Definition: blackoilintensivequantities.hh:257
OPM_HOST_DEVICE void updateCommonPart(const Problem &problem, const PrimaryVariables &priVars, const unsigned globalSpaceIdx, const unsigned timeIdx)
Definition: blackoilintensivequantities.hh:826
BlackOilIntensiveQuantities(const BlackOilIntensiveQuantities< OtherTypeTag > &other, const FluidSystem &fsystem)
Definition: blackoilintensivequantities.hh:187
OPM_HOST_DEVICE Scalar referencePorosity() const
Returns the porosity of the rock at reference conditions.
Definition: blackoilintensivequantities.hh:941
OPM_HOST_DEVICE void updateMobilityAndInvB()
Definition: blackoilintensivequantities.hh:524
OPM_HOST_DEVICE BlackOilIntensiveQuantities & operator=(const BlackOilIntensiveQuantities &other)=default
auto withOtherFluidSystem(const GetPropType< OtherTypeTag, Properties::FluidSystem > &other) const
Definition: blackoilintensivequantities.hh:211
OPM_HOST_DEVICE auto pvtRegionIndex() const -> decltype(std::declval< FluidState >().pvtRegionIndex())
Returns the index of the PVT region used to calculate the thermodynamic quantities.
Definition: blackoilintensivequantities.hh:923
OPM_HOST_DEVICE const Evaluation & mobility(unsigned phaseIdx) const
Returns the effective mobility of a given phase within the control volume.
Definition: blackoilintensivequantities.hh:871
OPM_HOST_DEVICE void updatePorosity(const ElementContext &elemCtx, unsigned dofIdx, unsigned timeIdx)
Definition: blackoilintensivequantities.hh:610
OPM_HOST_DEVICE void updatePhaseDensities()
Definition: blackoilintensivequantities.hh:565
OPM_HOST_DEVICE void updateRelpermAndPressures(const Problem &problem, const PrimaryVariables &priVars, const unsigned globalSpaceIdx, const unsigned timeIdx, const LinearizationType &lintype)
Definition: blackoilintensivequantities.hh:329
OPM_HOST_DEVICE FluidState & fluidState()
Definition: blackoilintensivequantities.hh:865
OPM_HOST_DEVICE void update(const Problem &problem, const PrimaryVariables &priVars, const unsigned globalSpaceIdx, const unsigned timeIdx)
Definition: blackoilintensivequantities.hh:800
OPM_HOST_DEVICE void updateTempSalt(const Problem &problem, const PrimaryVariables &priVars, const unsigned globalSpaceIdx, const unsigned timeIdx, const LinearizationType &lintype)
Definition: blackoilintensivequantities.hh:243
OPM_HOST_DEVICE const auto & getFluidSystem() const
Returns the fluid system used by this intensive quantities.
Definition: blackoilintensivequantities.hh:960
GetPropType< TypeTag, Properties::Problem > Problem
Definition: blackoilintensivequantities.hh:164
BlackOilFluidState< Scalar, FluidSystem, energyModuleType !=EnergyModules::NoTemperature, energyModuleType==EnergyModules::FullyImplicitThermal, compositionSwitchEnabled, enableVapwat, enableBrine, enableSaltPrecipitation, enableDisgasInWater, enableSolvent, Indices::numPhases > ScalarFluidState
Definition: blackoilintensivequantities.hh:163
OPM_HOST_DEVICE const FluidState & fluidState() const
Returns the phase state for the control-volume.
Definition: blackoilintensivequantities.hh:861
OPM_HOST_DEVICE Evaluation relativePermeability(unsigned phaseIdx) const
Returns the relative permeability of a given phase within the control volume.
Definition: blackoilintensivequantities.hh:929
BlackOilIntensiveQuantities(const BlackOilIntensiveQuantities &other)=default
OPM_HOST_DEVICE const Evaluation & permFactor() const
Definition: blackoilintensivequantities.hh:944
OPM_HOST_DEVICE BlackOilIntensiveQuantities()
Definition: blackoilintensivequantities.hh:166
void overlayBlackOilFieldsFrom(const BlackOilIntensiveQuantities< OtherTypeTag > &other)
Field-by-field overlay of the BlackOil intensive-quantity values from another BlackOilIntensiveQuanti...
Definition: blackoilintensivequantities.hh:226
OPM_HOST_DEVICE const Evaluation & rockCompTransMultiplier() const
Definition: blackoilintensivequantities.hh:913
OPM_HOST_DEVICE void assertFiniteMembers()
Definition: blackoilintensivequantities.hh:716
OPM_HOST_DEVICE const Evaluation & mobility(unsigned phaseIdx, FaceDir::DirEnum facedir) const
Definition: blackoilintensivequantities.hh:874
OPM_HOST_DEVICE void updatePorosity(const Problem &problem, const PrimaryVariables &priVars, const unsigned globalSpaceIdx, const unsigned timeIdx)
Definition: blackoilintensivequantities.hh:621
OPM_HOST_DEVICE const Evaluation & porosity() const
Returns the average porosity within the control volume.
Definition: blackoilintensivequantities.hh:907
BlackOilFluidState< Evaluation, FluidSystem, energyModuleType !=EnergyModules::NoTemperature, energyModuleType==EnergyModules::FullyImplicitThermal, compositionSwitchEnabled, enableVapwat, enableBrine, enableSaltPrecipitation, enableDisgasInWater, enableSolvent, Indices::numPhases > FluidState
Definition: blackoilintensivequantities.hh:152
OPM_HOST_DEVICE void updateRsRvRsw(const Problem &problem, const PrimaryVariables &priVars, const unsigned globalSpaceIdx, const unsigned timeIdx)
Definition: blackoilintensivequantities.hh:421
Provides the volumetric quantities required for the equations needed by the polymers extension of the...
Provides the volumetric quantities required for the equations needed by the solvents extension of the...
This file contains definitions related to directional mobilities.
Definition: blackoilbioeffectsmodules.hh:45
typename Properties::Detail::GetPropImpl< TypeTag, Property >::type::type GetPropType
get the type alias defined in the property (equivalent to old macro GET_PROP_TYPE(....
Definition: propertysystem.hh:233
Definition: linearizationtype.hh:34