70 :
public GetPropType<TypeTag, Properties::DiscIntensiveQuantities>
71 ,
public GetPropType<TypeTag, Properties::FluxModule>::FluxIntensiveQuantities
113 enum { waterCompIdx = FluidSystem::waterCompIdx };
114 enum { oilCompIdx = FluidSystem::oilCompIdx };
115 enum { gasCompIdx = FluidSystem::gasCompIdx };
116 enum { waterPhaseIdx = FluidSystem::waterPhaseIdx };
117 enum { oilPhaseIdx = FluidSystem::oilPhaseIdx };
118 enum { gasPhaseIdx = FluidSystem::gasPhaseIdx };
119 enum { dimWorld = GridView::dimensionworld };
120 enum { compositionSwitchIdx = Indices::compositionSwitchIdx };
122 static constexpr bool compositionSwitchEnabled = Indices::compositionSwitchIdx >= 0;
123 static constexpr bool waterEnabled = Indices::waterEnabled;
124 static constexpr bool gasEnabled = Indices::gasEnabled;
125 static constexpr bool oilEnabled = Indices::oilEnabled;
128 using DimMatrix = Dune::FieldMatrix<Scalar, dimWorld, dimWorld>;
129 using FluxIntensiveQuantities =
typename FluxModule::FluxIntensiveQuantities;
133 using DirectionalMobilityPtr = Opm::Utility::CopyablePtr<DirectionalMobility<TypeTag, Evaluation>>;
144 compositionSwitchEnabled,
147 enableSaltPrecipitation,
154 compositionSwitchEnabled,
157 enableSaltPrecipitation,
164 if (compositionSwitchEnabled) {
165 fluidState_.setRs(0.0);
166 fluidState_.setRv(0.0);
169 fluidState_.setRvw(0.0);
171 if (has_disgas_in_water) {
172 fluidState_.setRsw(0.0);
179 void updateTempSalt(
const ElementContext& elemCtx,
unsigned dofIdx,
unsigned timeIdx)
181 if constexpr (enableTemperature || enableEnergy) {
182 asImp_().updateTemperature_(elemCtx, dofIdx,
timeIdx);
185 if constexpr (enableBrine) {
186 asImp_().updateSaltConcentration_(elemCtx, dofIdx,
timeIdx);
190 void updateSaturations(
const ElementContext& elemCtx,
unsigned dofIdx,
unsigned timeIdx)
192 const auto& priVars = elemCtx.primaryVars(dofIdx,
timeIdx);
196 if constexpr (waterEnabled) {
197 if (priVars.primaryVarsMeaningWater() == PrimaryVariables::WaterMeaning::Sw) {
198 assert(Indices::waterSwitchIdx >= 0);
199 if constexpr (Indices::waterSwitchIdx >= 0) {
200 Sw = priVars.makeEvaluation(Indices::waterSwitchIdx,
timeIdx);
202 }
else if(priVars.primaryVarsMeaningWater() == PrimaryVariables::WaterMeaning::Rsw ||
203 priVars.primaryVarsMeaningWater() == PrimaryVariables::WaterMeaning::Disabled) {
210 if constexpr (gasEnabled) {
211 if (priVars.primaryVarsMeaningGas() == PrimaryVariables::GasMeaning::Sg) {
212 assert(Indices::compositionSwitchIdx >= 0);
213 if constexpr (compositionSwitchEnabled) {
214 Sg = priVars.makeEvaluation(Indices::compositionSwitchIdx,
timeIdx);
216 }
else if (priVars.primaryVarsMeaningGas() == PrimaryVariables::GasMeaning::Rv) {
218 }
else if (priVars.primaryVarsMeaningGas() == PrimaryVariables::GasMeaning::Disabled) {
219 if constexpr (waterEnabled) {
227 Valgrind::CheckDefined(Sg);
228 Valgrind::CheckDefined(Sw);
230 Evaluation So = 1.0 - Sw - Sg;
233 if constexpr (enableSolvent) {
234 if(priVars.primaryVarsMeaningSolvent() == PrimaryVariables::SolventMeaning::Ss) {
235 if (FluidSystem::phaseIsActive(oilPhaseIdx)) {
236 So -= priVars.makeEvaluation(Indices::solventSaturationIdx,
timeIdx);
237 }
else if (FluidSystem::phaseIsActive(gasPhaseIdx)) {
238 Sg -= priVars.makeEvaluation(Indices::solventSaturationIdx,
timeIdx);
243 if (FluidSystem::phaseIsActive(waterPhaseIdx))
244 fluidState_.setSaturation(waterPhaseIdx, Sw);
246 if (FluidSystem::phaseIsActive(gasPhaseIdx))
247 fluidState_.setSaturation(gasPhaseIdx, Sg);
249 if (FluidSystem::phaseIsActive(oilPhaseIdx))
250 fluidState_.setSaturation(oilPhaseIdx, So);
253 void updateRelpermAndPressures(
const ElementContext& elemCtx,
unsigned dofIdx,
unsigned timeIdx)
255 const auto& problem = elemCtx.problem();
256 const auto& priVars = elemCtx.primaryVars(dofIdx,
timeIdx);
263 if constexpr (enableSolvent) {
264 asImp_().solventPreSatFuncUpdate_(elemCtx, dofIdx,
timeIdx);
268 problem.updateRelperms(mobility_, dirMob_, fluidState_,
globalSpaceIdx);
271 std::array<Evaluation, numPhases>
pC;
276 if constexpr (enableBrine) {
277 if (BrineModule::hasPcfactTables() && priVars.primaryVarsMeaningBrine() == PrimaryVariables::BrineMeaning::Sp) {
279 const Evaluation Sp = priVars.makeEvaluation(Indices::saltConcentrationIdx,
timeIdx);
284 if (FluidSystem::phaseIsActive(
phaseIdx)) {
291 if (priVars.primaryVarsMeaningPressure() == PrimaryVariables::PressureMeaning::Pg) {
292 const Evaluation& pg = priVars.makeEvaluation(Indices::pressureSwitchIdx,
timeIdx);
294 if (FluidSystem::phaseIsActive(
phaseIdx))
296 }
else if (priVars.primaryVarsMeaningPressure() == PrimaryVariables::PressureMeaning::Pw) {
297 const Evaluation& pw = priVars.makeEvaluation(Indices::pressureSwitchIdx,
timeIdx);
299 if (FluidSystem::phaseIsActive(
phaseIdx))
302 assert(FluidSystem::phaseIsActive(oilPhaseIdx));
303 const Evaluation& po = priVars.makeEvaluation(Indices::pressureSwitchIdx,
timeIdx);
305 if (FluidSystem::phaseIsActive(
phaseIdx))
313 if constexpr (enableSolvent) {
314 asImp_().solventPostSatFuncUpdate_(elemCtx, dofIdx,
timeIdx);
319 Evaluation updateRsRvRsw(
const ElementContext& elemCtx,
unsigned dofIdx,
unsigned timeIdx)
321 const auto& problem = elemCtx.problem();
322 const auto& priVars = elemCtx.primaryVars(dofIdx,
timeIdx);
324 const unsigned pvtRegionIdx = priVars.pvtRegionIndex();
326 Scalar
RvMax = FluidSystem::enableVaporizedOil()
329 Scalar
RsMax = FluidSystem::enableDissolvedGas()
332 Scalar
RswMax = FluidSystem::enableDissolvedGasInWater()
336 Evaluation
SoMax = 0.0;
337 if (FluidSystem::phaseIsActive(FluidSystem::oilPhaseIdx)) {
338 SoMax = max(fluidState_.saturation(oilPhaseIdx),
343 if (priVars.primaryVarsMeaningGas() == PrimaryVariables::GasMeaning::Rs) {
344 const auto& Rs = priVars.makeEvaluation(Indices::compositionSwitchIdx,
timeIdx);
345 fluidState_.setRs(Rs);
347 if (FluidSystem::enableDissolvedGas()) {
348 const Evaluation&
RsSat = enableExtbo ? asImp_().rs() :
349 FluidSystem::saturatedDissolutionFactor(fluidState_,
355 else if constexpr (compositionSwitchEnabled)
356 fluidState_.setRs(0.0);
358 if (priVars.primaryVarsMeaningGas() == PrimaryVariables::GasMeaning::Rv) {
359 const auto& Rv = priVars.makeEvaluation(Indices::compositionSwitchIdx,
timeIdx);
360 fluidState_.setRv(Rv);
362 if (FluidSystem::enableVaporizedOil() ) {
363 const Evaluation&
RvSat = enableExtbo ? asImp_().rv() :
364 FluidSystem::saturatedDissolutionFactor(fluidState_,
370 else if constexpr (compositionSwitchEnabled)
371 fluidState_.setRv(0.0);
374 if (priVars.primaryVarsMeaningWater() == PrimaryVariables::WaterMeaning::Rvw) {
375 const auto& Rvw = priVars.makeEvaluation(Indices::waterSwitchIdx,
timeIdx);
376 fluidState_.setRvw(Rvw);
378 if (FluidSystem::enableVaporizedWater()) {
379 const Evaluation&
RvwSat = FluidSystem::saturatedVaporizationFactor(fluidState_,
382 fluidState_.setRvw(
RvwSat);
386 if (priVars.primaryVarsMeaningWater() == PrimaryVariables::WaterMeaning::Rsw) {
387 const auto& Rsw = priVars.makeEvaluation(Indices::waterSwitchIdx,
timeIdx);
388 fluidState_.setRsw(Rsw);
390 if (FluidSystem::enableDissolvedGasInWater()) {
391 const Evaluation&
RswSat = FluidSystem::saturatedDissolutionFactor(fluidState_,
401 void updateMobilityAndInvB()
403 const unsigned pvtRegionIdx = fluidState_.pvtRegionIndex();
407 std::vector<std::array<Evaluation,numPhases>*>
mobilities = {&mobility_};
409 for (
int i=0; i<3; i++) {
411 mobilities.push_back(&(dirMob_->getArray(i)));
415 if (!FluidSystem::phaseIsActive(
phaseIdx))
417 const auto&
b = FluidSystem::inverseFormationVolumeFactor(fluidState_,
phaseIdx, pvtRegionIdx);
419 const auto&
mu = FluidSystem::viscosity(fluidState_,
phaseIdx, pvtRegionIdx);
421 if (enableExtbo &&
phaseIdx == oilPhaseIdx) {
424 else if (enableExtbo &&
phaseIdx == gasPhaseIdx) {
432 Valgrind::CheckDefined(mobility_);
435 void updatePhaseDensities()
437 const unsigned pvtRegionIdx = fluidState_.pvtRegionIndex();
441 if (FluidSystem::phaseIsActive(waterPhaseIdx)) {
442 rho = fluidState_.invB(waterPhaseIdx);
443 rho *= FluidSystem::referenceDensity(waterPhaseIdx, pvtRegionIdx);
444 if (FluidSystem::enableDissolvedGasInWater()) {
446 fluidState_.invB(waterPhaseIdx) *
448 FluidSystem::referenceDensity(gasPhaseIdx, pvtRegionIdx);
450 fluidState_.setDensity(waterPhaseIdx, rho);
453 if (FluidSystem::phaseIsActive(gasPhaseIdx)) {
454 rho = fluidState_.invB(gasPhaseIdx);
455 rho *= FluidSystem::referenceDensity(gasPhaseIdx, pvtRegionIdx);
456 if (FluidSystem::enableVaporizedOil()) {
458 fluidState_.invB(gasPhaseIdx) *
460 FluidSystem::referenceDensity(oilPhaseIdx, pvtRegionIdx);
462 if (FluidSystem::enableVaporizedWater()) {
464 fluidState_.invB(gasPhaseIdx) *
466 FluidSystem::referenceDensity(waterPhaseIdx, pvtRegionIdx);
468 fluidState_.setDensity(gasPhaseIdx, rho);
471 if (FluidSystem::phaseIsActive(oilPhaseIdx)) {
472 rho = fluidState_.invB(oilPhaseIdx);
473 rho *= FluidSystem::referenceDensity(oilPhaseIdx, pvtRegionIdx);
474 if (FluidSystem::enableDissolvedGas()) {
476 fluidState_.invB(oilPhaseIdx) *
478 FluidSystem::referenceDensity(gasPhaseIdx, pvtRegionIdx);
480 fluidState_.setDensity(oilPhaseIdx, rho);
484 void updatePorosity(
const ElementContext& elemCtx,
unsigned dofIdx,
unsigned timeIdx)
486 const auto& problem = elemCtx.problem();
487 const auto& priVars = elemCtx.primaryVars(dofIdx,
timeIdx);
488 const auto& linearizationType = problem.model().linearizer().getLinearizationType();
492 referencePorosity_ = problem.porosity(elemCtx, dofIdx,
timeIdx);
493 porosity_ = referencePorosity_;
497 Scalar rockCompressibility = problem.rockCompressibility(
globalSpaceIdx);
498 if (rockCompressibility > 0.0) {
501 if (FluidSystem::phaseIsActive(oilPhaseIdx)) {
502 x = rockCompressibility*(fluidState_.pressure(oilPhaseIdx) -
rockRefPressure);
503 }
else if (FluidSystem::phaseIsActive(waterPhaseIdx)){
504 x = rockCompressibility*(fluidState_.pressure(waterPhaseIdx) -
rockRefPressure);
506 x = rockCompressibility*(fluidState_.pressure(gasPhaseIdx) -
rockRefPressure);
508 porosity_ *= 1.0 + x + 0.5*x*x;
515 if constexpr (enableMICP){
516 Evaluation
biofilm_ = priVars.makeEvaluation(Indices::biofilmConcentrationIdx,
timeIdx, linearizationType);
517 Evaluation
calcite_ = priVars.makeEvaluation(Indices::calciteConcentrationIdx,
timeIdx, linearizationType);
523 if (enableSaltPrecipitation && priVars.primaryVarsMeaningBrine() == PrimaryVariables::BrineMeaning::Sp) {
524 Evaluation Sp = priVars.makeEvaluation(Indices::saltConcentrationIdx,
timeIdx);
525 porosity_ *= (1.0 - Sp);
529 void assertFiniteMembers()
533 if (!FluidSystem::phaseIsActive(
phaseIdx))
549 void update(
const ElementContext& elemCtx,
unsigned dofIdx,
unsigned timeIdx)
551 ParentType::update(elemCtx, dofIdx,
timeIdx);
555 const auto& problem = elemCtx.problem();
556 const auto& priVars = elemCtx.primaryVars(dofIdx,
timeIdx);
558 const unsigned pvtRegionIdx = priVars.pvtRegionIndex();
560 fluidState_.setPvtRegionIndex(pvtRegionIdx);
562 updateTempSalt(elemCtx, dofIdx,
timeIdx);
563 updateSaturations(elemCtx, dofIdx,
timeIdx);
564 updateRelpermAndPressures(elemCtx, dofIdx,
timeIdx);
567 if constexpr (enableExtbo) {
568 asImp_().zFractionUpdate_(elemCtx, dofIdx,
timeIdx);
571 Evaluation
SoMax = updateRsRvRsw(elemCtx, dofIdx,
timeIdx);
573 updateMobilityAndInvB();
574 updatePhaseDensities();
575 updatePorosity(elemCtx, dofIdx,
timeIdx);
579 if constexpr (enableSolvent) {
580 asImp_().solventPvtUpdate_(elemCtx, dofIdx,
timeIdx);
582 if constexpr (enableExtbo) {
583 asImp_().zPvtUpdate_();
585 if constexpr (enablePolymer) {
586 asImp_().polymerPropertiesUpdate_(elemCtx, dofIdx,
timeIdx);
591 if (FluidSystem::phaseIsActive(FluidSystem::oilPhaseIdx)) {
596 if constexpr (enableEnergy) {
599 if constexpr (enableFoam) {
600 asImp_().foamPropertiesUpdate_(elemCtx, dofIdx,
timeIdx);
602 if constexpr (enableMICP) {
603 asImp_().MICPPropertiesUpdate_(elemCtx, dofIdx,
timeIdx);
605 if constexpr (enableBrine) {
606 asImp_().saltPropertiesUpdate_(elemCtx, dofIdx,
timeIdx);
608 if constexpr (enableConvectiveMixing) {
611 if (problem.simulator().vanguard().eclState().runspec().co2Storage()) {
612 if (problem.drsdtconIsActive(
globalSpaceIdx, problem.simulator().episodeIndex())) {
613 asImp_().updateSaturatedDissolutionFactor_();
620 FluxIntensiveQuantities::update_(elemCtx, dofIdx,
timeIdx);
623 DiffusionIntensiveQuantities::update_(fluidState_,
paramCache, elemCtx, dofIdx,
timeIdx);
626 DispersionIntensiveQuantities::update_(elemCtx, dofIdx,
timeIdx);
629 assertFiniteMembers();
637 {
return fluidState_; }
647 using Dir = FaceDir::DirEnum;
652 return dirMob_->mobilityX_[
phaseIdx];
655 return dirMob_->mobilityY_[
phaseIdx];
658 return dirMob_->mobilityZ_[
phaseIdx];
660 throw std::runtime_error(
"Unexpected face direction");
673 {
return porosity_; }
679 {
return rockCompTransMultiplier_; }
690 {
return fluidState_.pvtRegionIndex(); }
708 {
return referencePorosity_; }
710 const Evaluation& permFactor()
const
712 if constexpr (enableMICP) {
713 return MICPIntQua::permFactor();
715 else if constexpr (enableSaltPrecipitation) {
716 return BrineIntQua::permFactor();
719 throw std::logic_error(
"permFactor() called but salt precipitation or MICP are disabled");
724 friend BlackOilSolventIntensiveQuantities<TypeTag>;
725 friend BlackOilExtboIntensiveQuantities<TypeTag>;
726 friend BlackOilPolymerIntensiveQuantities<TypeTag>;
727 friend BlackOilEnergyIntensiveQuantities<TypeTag>;
728 friend BlackOilFoamIntensiveQuantities<TypeTag>;
730 friend BlackOilMICPIntensiveQuantities<TypeTag>;
732 Implementation& asImp_()
733 {
return *
static_cast<Implementation*
>(
this); }
735 FluidState fluidState_;
736 Scalar referencePorosity_;
737 Evaluation porosity_;
738 Evaluation rockCompTransMultiplier_;
739 std::array<Evaluation,numPhases> mobility_;
756 DirectionalMobilityPtr dirMob_;