28 #ifndef OPM_BLACK_OIL_INTENSIVE_QUANTITIES_GLOBAL_INDEX_HPP 29 #define OPM_BLACK_OIL_INTENSIVE_QUANTITIES_GLOBAL_INDEX_HPP 33 #include <dune/common/fmatrix.hh> 35 #include <opm/common/ErrorMacros.hpp> 36 #include <opm/common/OpmLog/OpmLog.hpp> 38 #include <opm/input/eclipse/EclipseState/Grid/FaceDir.hpp> 40 #include <opm/material/fluidstates/BlackOilFluidState.hpp> 41 #include <opm/material/common/Valgrind.hpp> 48 #include <opm/utility/CopyablePtr.hpp> 53 #include <fmt/format.h> 64 template <
class TypeTag>
66 :
public GetPropType<TypeTag, Properties::DiscIntensiveQuantities>
67 ,
public GetPropType<TypeTag, Properties::FluxModule>::FluxIntensiveQuantities
73 ,
public BlackOilBrineIntensiveQuantities<TypeTag, getPropValue<TypeTag, Properties::EnableBrine>()>
91 enum { numEq = getPropValue<TypeTag, Properties::NumEq>() };
92 enum { enableSolvent = getPropValue<TypeTag, Properties::EnableSolvent>() };
93 enum { enableExtbo = getPropValue<TypeTag, Properties::EnableExtbo>() };
94 enum { enablePolymer = getPropValue<TypeTag, Properties::EnablePolymer>() };
95 enum { enableFoam = getPropValue<TypeTag, Properties::EnableFoam>() };
96 enum { enableBrine = getPropValue<TypeTag, Properties::EnableBrine>() };
97 enum { enableVapwat = getPropValue<TypeTag, Properties::EnableVapwat>() };
98 enum { enableSaltPrecipitation = getPropValue<TypeTag, Properties::EnableSaltPrecipitation>() };
99 static constexpr EnergyModules energyModuleType = getPropValue<TypeTag, Properties::EnergyModuleType>();
100 enum { enableDiffusion = getPropValue<TypeTag, Properties::EnableDiffusion>() };
101 enum { enableConvectiveMixing = getPropValue<TypeTag, Properties::EnableConvectiveMixing>() };
102 enum { enableBioeffects = getPropValue<TypeTag, Properties::EnableBioeffects>() };
103 enum { numPhases = getPropValue<TypeTag, Properties::NumPhases>() };
104 enum { numComponents = getPropValue<TypeTag, Properties::NumComponents>() };
105 enum { waterCompIdx = FluidSystem::waterCompIdx };
106 enum { oilCompIdx = FluidSystem::oilCompIdx };
107 enum { gasCompIdx = FluidSystem::gasCompIdx };
108 enum { waterPhaseIdx = FluidSystem::waterPhaseIdx };
109 enum { oilPhaseIdx = FluidSystem::oilPhaseIdx };
110 enum { gasPhaseIdx = FluidSystem::gasPhaseIdx };
111 enum { dimWorld = GridView::dimensionworld };
112 enum { compositionSwitchIdx = Indices::compositionSwitchIdx };
114 static constexpr
bool compositionSwitchEnabled = Indices::compositionSwitchIdx >= 0;
115 static constexpr
bool waterEnabled = Indices::waterEnabled;
116 static constexpr
bool gasEnabled = Indices::gasEnabled;
117 static constexpr
bool oilEnabled = Indices::oilEnabled;
119 using Toolbox = MathToolbox<Evaluation>;
120 using DimMatrix = Dune::FieldMatrix<Scalar, dimWorld, dimWorld>;
121 using FluxIntensiveQuantities =
typename FluxModule::FluxIntensiveQuantities;
124 using DirectionalMobilityPtr = Utility::CopyablePtr<DirectionalMobility<TypeTag>>;
127 using FluidState = BlackOilFluidState<Evaluation,
129 energyModuleType != EnergyModules::NoTemperature,
130 energyModuleType == EnergyModules::FullyImplicitThermal,
131 compositionSwitchEnabled,
134 enableSaltPrecipitation,
142 if constexpr (compositionSwitchEnabled) {
143 fluidState_.setRs(0.0);
144 fluidState_.setRv(0.0);
146 if constexpr (enableVapwat) {
147 fluidState_.setRvw(0.0);
154 void update(
const ElementContext& elemCtx,
unsigned dofIdx,
unsigned timeIdx)
156 ParentType::update(elemCtx, dofIdx, timeIdx);
158 const auto& problem = elemCtx.problem();
159 const auto& priVars = elemCtx.primaryVars(dofIdx, timeIdx);
160 unsigned globalSpaceIdx = elemCtx.globalSpaceIndex(dofIdx, timeIdx);
161 this->
update(problem,priVars,globalSpaceIdx,timeIdx);
164 void update(
const Problem& problem,
165 const PrimaryVariables& priVars,
166 unsigned globalSpaceIdx,
170 this->extrusionFactor_ = 1.0;
171 OPM_TIMEBLOCK_LOCAL(UpdateIntensiveQuantities, Subsystem::PvtProps | Subsystem::SatProps);
172 Scalar RvMax = FluidSystem::enableVaporizedOil()
173 ? problem.maxOilVaporizationFactor(timeIdx, globalSpaceIdx)
175 Scalar RsMax = FluidSystem::enableDissolvedGas()
176 ? problem.maxGasDissolutionFactor(timeIdx, globalSpaceIdx)
179 asImp_().updateTemperature_(problem, priVars, globalSpaceIdx, timeIdx);
181 unsigned pvtRegionIdx = priVars.pvtRegionIndex();
182 fluidState_.setPvtRegionIndex(pvtRegionIdx);
188 if constexpr (waterEnabled) {
189 if (priVars.primaryVarsMeaningWater() == PrimaryVariables::WaterMeaning::Sw) {
190 Sw = priVars.makeEvaluation(Indices::waterSwitchIdx, timeIdx);
191 }
else if (priVars.primaryVarsMeaningWater() == PrimaryVariables::WaterMeaning::Disabled) {
197 if constexpr (gasEnabled) {
198 if (priVars.primaryVarsMeaningGas() == PrimaryVariables::GasMeaning::Sg) {
199 Sg = priVars.makeEvaluation(Indices::compositionSwitchIdx, timeIdx);
200 }
else if (priVars.primaryVarsMeaningGas() == PrimaryVariables::GasMeaning::Rv) {
202 }
else if (priVars.primaryVarsMeaningGas() == PrimaryVariables::GasMeaning::Disabled) {
203 if constexpr (waterEnabled) {
211 Valgrind::CheckDefined(Sg);
212 Valgrind::CheckDefined(Sw);
214 Evaluation So = 1.0 - Sw - Sg;
217 if constexpr (enableSolvent) {
218 So -= priVars.makeEvaluation(Indices::solventSaturationIdx, timeIdx);
221 if (FluidSystem::phaseIsActive(waterPhaseIdx)) {
222 fluidState_.setSaturation(waterPhaseIdx, Sw);
225 if (FluidSystem::phaseIsActive(gasPhaseIdx)) {
226 fluidState_.setSaturation(gasPhaseIdx, Sg);
229 if (FluidSystem::phaseIsActive(oilPhaseIdx)) {
230 fluidState_.setSaturation(oilPhaseIdx, So);
233 std::array<Evaluation, numPhases> pC{};
234 computeRelpermAndPC(mobility_, pC, problem, fluidState_, globalSpaceIdx);
236 if (priVars.primaryVarsMeaningPressure() == PrimaryVariables::PressureMeaning::Pg) {
237 const Evaluation& pg = priVars.makeEvaluation(Indices::pressureSwitchIdx, timeIdx);
238 for (
unsigned phaseIdx = 0; phaseIdx < numPhases; ++phaseIdx) {
239 if (FluidSystem::phaseIsActive(phaseIdx)) {
240 fluidState_.setPressure(phaseIdx, pg + (pC[phaseIdx] - pC[gasPhaseIdx]));
244 const Evaluation& po = priVars.makeEvaluation(Indices::pressureSwitchIdx, timeIdx);
245 for (
unsigned phaseIdx = 0; phaseIdx < numPhases; ++phaseIdx) {
246 if (FluidSystem::phaseIsActive(phaseIdx)) {
247 fluidState_.setPressure(phaseIdx, po + (pC[phaseIdx] - pC[oilPhaseIdx]));
252 Evaluation SoMax = 0.0;
253 if (FluidSystem::phaseIsActive(FluidSystem::oilPhaseIdx)) {
254 SoMax = max(fluidState_.saturation(oilPhaseIdx),
255 problem.maxOilSaturation(globalSpaceIdx));
260 if (priVars.primaryVarsMeaningGas() == PrimaryVariables::GasMeaning::Rs) {
261 const auto& Rs = priVars.makeEvaluation(Indices::compositionSwitchIdx, timeIdx);
262 fluidState_.setRs(Rs);
264 if (FluidSystem::enableDissolvedGas()) {
265 OPM_TIMEBLOCK_LOCAL(UpdateSaturatedRs, Subsystem::PvtProps);
266 if constexpr (enableExtbo) {
267 fluidState_.setRs(min(RsMax, asImp_().rs()));
270 const Evaluation& RsSat =
271 FluidSystem::saturatedDissolutionFactor(fluidState_,
275 fluidState_.setRs(min(RsMax, RsSat));
278 else if constexpr (compositionSwitchEnabled) {
279 fluidState_.setRs(0.0);
283 if (priVars.primaryVarsMeaningGas() == PrimaryVariables::GasMeaning::Rv) {
284 const auto& Rv = priVars.makeEvaluation(Indices::compositionSwitchIdx, timeIdx);
285 fluidState_.setRv(Rv);
287 if (FluidSystem::enableVaporizedOil() ) {
288 OPM_TIMEBLOCK_LOCAL(UpdateSaturatedRv, Subsystem::PvtProps);
290 if constexpr (enableExtbo) {
291 fluidState_.setRv(min(RvMax, asImp_().rv()));
294 const Evaluation& RvSat =
295 FluidSystem::saturatedDissolutionFactor(fluidState_,
299 fluidState_.setRv(min(RvMax, RvSat));
302 else if constexpr (compositionSwitchEnabled) {
303 fluidState_.setRv(0.0);
307 if constexpr (enableVapwat) {
308 if (priVars.primaryVarsMeaningWater() == PrimaryVariables::WaterMeaning::Rvw) {
309 const auto& Rvw = priVars.makeEvaluation(Indices::waterSwitchIdx, timeIdx);
310 fluidState_.setRvw(Rvw);
313 if (FluidSystem::enableVaporizedWater()) {
314 OPM_TIMEBLOCK_LOCAL(UpdateSaturatedRv, Subsystem::PvtProps);
315 const Evaluation& RvwSat = FluidSystem::saturatedVaporizationFactor(fluidState_,
318 fluidState_.setRvw(RvwSat);
323 for (
unsigned phaseIdx = 0; phaseIdx < numPhases; ++phaseIdx) {
324 if (!FluidSystem::phaseIsActive(phaseIdx)) {
327 computeInverseFormationVolumeFactorAndViscosity(fluidState_, phaseIdx, pvtRegionIdx);
329 Valgrind::CheckDefined(mobility_);
333 if (FluidSystem::phaseIsActive(waterPhaseIdx)) {
334 OPM_TIMEBLOCK_LOCAL(UpdateWDensity, Subsystem::PvtProps);
335 rho = fluidState_.invB(waterPhaseIdx);
336 rho *= FluidSystem::referenceDensity(waterPhaseIdx, pvtRegionIdx);
337 fluidState_.setDensity(waterPhaseIdx, rho);
340 if (FluidSystem::phaseIsActive(gasPhaseIdx)) {
341 OPM_TIMEBLOCK_LOCAL(UpdateGDensity, Subsystem::PvtProps);
342 rho = fluidState_.invB(gasPhaseIdx);
343 rho *= FluidSystem::referenceDensity(gasPhaseIdx, pvtRegionIdx);
344 if (FluidSystem::enableVaporizedOil()) {
345 rho += fluidState_.invB(gasPhaseIdx) *
347 FluidSystem::referenceDensity(oilPhaseIdx, pvtRegionIdx);
349 if (FluidSystem::enableVaporizedWater()) {
350 rho += fluidState_.invB(gasPhaseIdx) *
352 FluidSystem::referenceDensity(waterPhaseIdx, pvtRegionIdx);
354 fluidState_.setDensity(gasPhaseIdx, rho);
357 if (FluidSystem::phaseIsActive(oilPhaseIdx)) {
358 OPM_TIMEBLOCK_LOCAL(UpdateODensity, Subsystem::PvtProps);
359 rho = fluidState_.invB(oilPhaseIdx);
360 rho *= FluidSystem::referenceDensity(oilPhaseIdx, pvtRegionIdx);
361 if (FluidSystem::enableDissolvedGas()) {
362 rho += fluidState_.invB(oilPhaseIdx) *
364 FluidSystem::referenceDensity(gasPhaseIdx, pvtRegionIdx);
366 fluidState_.setDensity(oilPhaseIdx, rho);
370 referencePorosity_ = problem.porosity(globalSpaceIdx,timeIdx);
371 porosity_ = referencePorosity_;
374 Scalar rockCompressibility = problem.rockCompressibility(globalSpaceIdx);
375 if (rockCompressibility > 0.0) {
376 OPM_TIMEBLOCK_LOCAL(UpdateRockCompressibility, Subsystem::PvtProps);
377 Scalar rockRefPressure = problem.rockReferencePressure(globalSpaceIdx);
379 if (FluidSystem::phaseIsActive(oilPhaseIdx)) {
380 x = rockCompressibility*(fluidState_.pressure(oilPhaseIdx) - rockRefPressure);
381 }
else if (FluidSystem::phaseIsActive(waterPhaseIdx)) {
382 x = rockCompressibility*(fluidState_.pressure(waterPhaseIdx) - rockRefPressure);
384 x = rockCompressibility*(fluidState_.pressure(gasPhaseIdx) - rockRefPressure);
386 porosity_ *= 1.0 + x + 0.5 * x * x;
390 porosity_ *= problem.template rockCompPoroMultiplier<Evaluation>(*
this, globalSpaceIdx);
392 rockCompTransMultiplier_ = problem.template rockCompTransMultiplier<Evaluation>(*
this, globalSpaceIdx);
394 if constexpr (enableConvectiveMixing) {
395 asImp_().updateSaturatedDissolutionFactor_();
400 for (
unsigned phaseIdx = 0; phaseIdx < numPhases; ++ phaseIdx) {
401 if (!FluidSystem::phaseIsActive(phaseIdx)) {
405 assert(isfinite(fluidState_.density(phaseIdx)));
406 assert(isfinite(fluidState_.saturation(phaseIdx)));
407 assert(isfinite(fluidState_.temperature(phaseIdx)));
408 assert(isfinite(fluidState_.pressure(phaseIdx)));
409 assert(isfinite(fluidState_.invB(phaseIdx)));
411 assert(isfinite(fluidState_.Rs()));
412 assert(isfinite(fluidState_.Rv()));
420 {
return fluidState_; }
425 const Evaluation&
mobility(
unsigned phaseIdx)
const 426 {
return mobility_[phaseIdx]; }
428 const Evaluation&
mobility(
unsigned phaseIdx, FaceDir::DirEnum facedir)
const 430 using Dir = FaceDir::DirEnum;
434 return dirMob_->getArray(0)[phaseIdx];
436 return dirMob_->getArray(1)[phaseIdx];
438 return dirMob_->getArray(2)[phaseIdx];
440 throw std::runtime_error(
"Unexpected face direction");
443 return mobility_[phaseIdx];
447 void computeInverseFormationVolumeFactorAndViscosity(FluidState&
fluidState,
449 unsigned pvtRegionIdx) {
450 OPM_TIMEBLOCK_LOCAL(UpdateInverseFormationFactorAndViscosity, Subsystem::PvtProps);
452 OPM_TIMEBLOCK_LOCAL(UpdateFormationFactor, Subsystem::PvtProps);
453 const auto& b = FluidSystem::inverseFormationVolumeFactor(
fluidState, phaseIdx, pvtRegionIdx);
454 fluidState_.setInvB(phaseIdx, b);
457 OPM_TIMEBLOCK_LOCAL(UpdateViscosity, Subsystem::PvtProps);
458 typename FluidSystem::template ParameterCache<Evaluation> paramCache;
459 paramCache.setRegionIndex(pvtRegionIdx);
460 paramCache.updateAll(fluidState_);
462 const auto& mu = FluidSystem::viscosity(
fluidState, paramCache, phaseIdx);
463 mobility_[phaseIdx] /= mu;
467 void computeRelpermAndPC(std::array<Evaluation,numPhases>&
mobility,
468 std::array<Evaluation, numPhases>& pC,
469 const Problem& problem,
471 unsigned globalSpaceIdx){
472 OPM_TIMEBLOCK_LOCAL(UpdateRelperm, Subsystem::SatProps);
473 const auto& materialParams = problem.materialLawParams(globalSpaceIdx);
474 MaterialLaw::capillaryPressures(pC, materialParams, fluidState_);
482 {
return porosity_; }
488 {
return rockCompTransMultiplier_; }
504 {
return fluidState_.pvtRegionIndex(); }
512 return fluidState_.viscosity(phaseIdx)*
mobility(phaseIdx);
522 {
return referencePorosity_; }
524 const Evaluation& permFactor()
const 526 throw std::logic_error(
"permFactor() is not yet implemented for compositional modeling");
534 return fluidState_.fluidSystem();
543 friend BlackOilBrineIntensiveQuantities<TypeTag, enableBrine>;
546 Implementation& asImp_()
547 {
return *
static_cast<Implementation*
>(
this); }
549 FluidState fluidState_;
550 Scalar referencePorosity_;
551 Evaluation porosity_;
552 Evaluation rockCompTransMultiplier_;
553 std::array<Evaluation,numPhases> mobility_;
570 DirectionalMobilityPtr dirMob_;
Contains the classes required to extend the black-oil model by energy.
Provides the volumetric quantities required for the equations needed by the convective mixing (DRSDTC...
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: BlackOilEnergyIntensiveQuantitiesGlobalIndex.hpp:36
Classes required for dynamic convective mixing.
const Evaluation & porosity() const
Returns the average porosity within the control volume.
Definition: BlackOilIntensiveQuantitiesGlobalIndex.hpp:481
Provides the volumetric quantities required for the calculation of molecular diffusive fluxes...
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.
Contains the quantities which are are constant within a finite volume in the black-oil model using gl...
Definition: BlackOilIntensiveQuantitiesGlobalIndex.hpp:65
Declares the properties required by the black oil model.
const Evaluation & rockCompTransMultiplier() const
The pressure-dependent transmissibility multiplier due to rock compressibility.
Definition: BlackOilIntensiveQuantitiesGlobalIndex.hpp:487
auto pvtRegionIndex() const -> decltype(std::declval< FluidState >().pvtRegionIndex())
Returns the index of the PVT region used to calculate the thermodynamic quantities.
Definition: BlackOilIntensiveQuantitiesGlobalIndex.hpp:503
Provides the volumetric quantities required for the equations needed by the polymers extension of the...
OPM_HOST_DEVICE const auto & getFluidSystem() const
Returns the fluid system used by this intensive quantities.
Definition: BlackOilIntensiveQuantitiesGlobalIndex.hpp:532
Provides the volumetric quantities required for the equations needed by the polymers extension of the...
const Evaluation & mobility(unsigned phaseIdx) const
Returns the effective mobility of a given phase within the control volume.
Definition: BlackOilIntensiveQuantitiesGlobalIndex.hpp:425
Evaluation relativePermeability(unsigned phaseIdx) const
Returns the relative permeability of a given phase within the control volume.
Definition: BlackOilIntensiveQuantitiesGlobalIndex.hpp:509
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 solvents extension of the...
This file contains definitions related to directional mobilities.
const FluidState & fluidState() const
Returns the phase state for the control-volume.
Definition: BlackOilIntensiveQuantitiesGlobalIndex.hpp:419
void update(const ElementContext &elemCtx, unsigned dofIdx, unsigned timeIdx)
Definition: BlackOilIntensiveQuantitiesGlobalIndex.hpp:154
Provides the volumetric quantities required for the equations needed by the bioeffects extension of t...
Scalar referencePorosity() const
Returns the porosity of the rock at reference conditions.
Definition: BlackOilIntensiveQuantitiesGlobalIndex.hpp:521