69 :
public GetPropType<TypeTag, Properties::DiscIntensiveQuantities>
70 ,
public GetPropType<TypeTag, Properties::FluxModule>::FluxIntensiveQuantities
110 enum { waterCompIdx = FluidSystem::waterCompIdx };
111 enum { oilCompIdx = FluidSystem::oilCompIdx };
112 enum { gasCompIdx = FluidSystem::gasCompIdx };
113 enum { waterPhaseIdx = FluidSystem::waterPhaseIdx };
114 enum { oilPhaseIdx = FluidSystem::oilPhaseIdx };
115 enum { gasPhaseIdx = FluidSystem::gasPhaseIdx };
116 enum { dimWorld = GridView::dimensionworld };
117 enum { compositionSwitchIdx = Indices::compositionSwitchIdx };
119 static constexpr bool compositionSwitchEnabled = Indices::compositionSwitchIdx >= 0;
120 static constexpr bool waterEnabled = Indices::waterEnabled;
121 static constexpr bool gasEnabled = Indices::gasEnabled;
122 static constexpr bool oilEnabled = Indices::oilEnabled;
125 using DimMatrix = Dune::FieldMatrix<Scalar, dimWorld, dimWorld>;
126 using FluxIntensiveQuantities =
typename FluxModule::FluxIntensiveQuantities;
130 using DirectionalMobilityPtr = Opm::Utility::CopyablePtr<DirectionalMobility<TypeTag, Evaluation>>;
139 compositionSwitchEnabled,
142 enableSaltPrecipitation,
149 compositionSwitchEnabled,
152 enableSaltPrecipitation,
159 if (compositionSwitchEnabled) {
160 fluidState_.setRs(0.0);
161 fluidState_.setRv(0.0);
164 fluidState_.setRvw(0.0);
166 if (has_disgas_in_water) {
167 fluidState_.setRsw(0.0);
174 void updateTempSalt(
const ElementContext& elemCtx,
unsigned dofIdx,
unsigned timeIdx)
176 if constexpr (enableTemperature || enableEnergy) {
177 asImp_().updateTemperature_(elemCtx, dofIdx,
timeIdx);
180 if constexpr (enableBrine) {
181 asImp_().updateSaltConcentration_(elemCtx, dofIdx,
timeIdx);
185 void updateSaturations(
const ElementContext& elemCtx,
unsigned dofIdx,
unsigned timeIdx)
187 const auto& priVars = elemCtx.primaryVars(dofIdx,
timeIdx);
191 if constexpr (waterEnabled) {
192 if (priVars.primaryVarsMeaningWater() == PrimaryVariables::WaterMeaning::Sw) {
193 assert(Indices::waterSwitchIdx >= 0);
194 if constexpr (Indices::waterSwitchIdx >= 0) {
195 Sw = priVars.makeEvaluation(Indices::waterSwitchIdx,
timeIdx);
197 }
else if(priVars.primaryVarsMeaningWater() == PrimaryVariables::WaterMeaning::Rsw ||
198 priVars.primaryVarsMeaningWater() == PrimaryVariables::WaterMeaning::Disabled) {
205 if constexpr (gasEnabled) {
206 if (priVars.primaryVarsMeaningGas() == PrimaryVariables::GasMeaning::Sg) {
207 assert(Indices::compositionSwitchIdx >= 0);
208 if constexpr (compositionSwitchEnabled) {
209 Sg = priVars.makeEvaluation(Indices::compositionSwitchIdx,
timeIdx);
211 }
else if (priVars.primaryVarsMeaningGas() == PrimaryVariables::GasMeaning::Rv) {
213 }
else if (priVars.primaryVarsMeaningGas() == PrimaryVariables::GasMeaning::Disabled) {
214 if constexpr (waterEnabled) {
222 Valgrind::CheckDefined(Sg);
223 Valgrind::CheckDefined(Sw);
225 Evaluation So = 1.0 - Sw - Sg;
228 if constexpr (enableSolvent) {
229 if(priVars.primaryVarsMeaningSolvent() == PrimaryVariables::SolventMeaning::Ss) {
230 if (FluidSystem::phaseIsActive(oilPhaseIdx)) {
231 So -= priVars.makeEvaluation(Indices::solventSaturationIdx,
timeIdx);
232 }
else if (FluidSystem::phaseIsActive(gasPhaseIdx)) {
233 Sg -= priVars.makeEvaluation(Indices::solventSaturationIdx,
timeIdx);
238 if (FluidSystem::phaseIsActive(waterPhaseIdx))
239 fluidState_.setSaturation(waterPhaseIdx, Sw);
241 if (FluidSystem::phaseIsActive(gasPhaseIdx))
242 fluidState_.setSaturation(gasPhaseIdx, Sg);
244 if (FluidSystem::phaseIsActive(oilPhaseIdx))
245 fluidState_.setSaturation(oilPhaseIdx, So);
248 void updateRelpermAndPressures(
const ElementContext& elemCtx,
unsigned dofIdx,
unsigned timeIdx)
250 const auto& problem = elemCtx.problem();
251 const auto& priVars = elemCtx.primaryVars(dofIdx,
timeIdx);
258 if constexpr (enableSolvent) {
259 asImp_().solventPreSatFuncUpdate_(elemCtx, dofIdx,
timeIdx);
263 problem.updateRelperms(mobility_, dirMob_, fluidState_,
globalSpaceIdx);
266 std::array<Evaluation, numPhases>
pC;
271 if constexpr (enableBrine) {
272 if (BrineModule::hasPcfactTables() && priVars.primaryVarsMeaningBrine() == PrimaryVariables::BrineMeaning::Sp) {
274 const Evaluation Sp = priVars.makeEvaluation(Indices::saltConcentrationIdx,
timeIdx);
279 if (FluidSystem::phaseIsActive(
phaseIdx)) {
286 if (priVars.primaryVarsMeaningPressure() == PrimaryVariables::PressureMeaning::Pg) {
287 const Evaluation& pg = priVars.makeEvaluation(Indices::pressureSwitchIdx,
timeIdx);
289 if (FluidSystem::phaseIsActive(
phaseIdx))
291 }
else if (priVars.primaryVarsMeaningPressure() == PrimaryVariables::PressureMeaning::Pw) {
292 const Evaluation& pw = priVars.makeEvaluation(Indices::pressureSwitchIdx,
timeIdx);
294 if (FluidSystem::phaseIsActive(
phaseIdx))
297 assert(FluidSystem::phaseIsActive(oilPhaseIdx));
298 const Evaluation& po = priVars.makeEvaluation(Indices::pressureSwitchIdx,
timeIdx);
300 if (FluidSystem::phaseIsActive(
phaseIdx))
308 if constexpr (enableSolvent) {
309 asImp_().solventPostSatFuncUpdate_(elemCtx, dofIdx,
timeIdx);
314 Evaluation updateRsRvRsw(
const ElementContext& elemCtx,
unsigned dofIdx,
unsigned timeIdx)
316 const auto& problem = elemCtx.problem();
317 const auto& priVars = elemCtx.primaryVars(dofIdx,
timeIdx);
319 const unsigned pvtRegionIdx = priVars.pvtRegionIndex();
321 Scalar
RvMax = FluidSystem::enableVaporizedOil()
324 Scalar
RsMax = FluidSystem::enableDissolvedGas()
327 Scalar
RswMax = FluidSystem::enableDissolvedGasInWater()
331 Evaluation
SoMax = 0.0;
332 if (FluidSystem::phaseIsActive(FluidSystem::oilPhaseIdx)) {
333 SoMax = max(fluidState_.saturation(oilPhaseIdx),
338 if (priVars.primaryVarsMeaningGas() == PrimaryVariables::GasMeaning::Rs) {
339 const auto& Rs = priVars.makeEvaluation(Indices::compositionSwitchIdx,
timeIdx);
340 fluidState_.setRs(Rs);
342 if (FluidSystem::enableDissolvedGas()) {
343 const Evaluation&
RsSat = enableExtbo ? asImp_().rs() :
344 FluidSystem::saturatedDissolutionFactor(fluidState_,
350 else if constexpr (compositionSwitchEnabled)
351 fluidState_.setRs(0.0);
353 if (priVars.primaryVarsMeaningGas() == PrimaryVariables::GasMeaning::Rv) {
354 const auto& Rv = priVars.makeEvaluation(Indices::compositionSwitchIdx,
timeIdx);
355 fluidState_.setRv(Rv);
357 if (FluidSystem::enableVaporizedOil() ) {
358 const Evaluation&
RvSat = enableExtbo ? asImp_().rv() :
359 FluidSystem::saturatedDissolutionFactor(fluidState_,
365 else if constexpr (compositionSwitchEnabled)
366 fluidState_.setRv(0.0);
369 if (priVars.primaryVarsMeaningWater() == PrimaryVariables::WaterMeaning::Rvw) {
370 const auto& Rvw = priVars.makeEvaluation(Indices::waterSwitchIdx,
timeIdx);
371 fluidState_.setRvw(Rvw);
373 if (FluidSystem::enableVaporizedWater()) {
374 const Evaluation&
RvwSat = FluidSystem::saturatedVaporizationFactor(fluidState_,
377 fluidState_.setRvw(
RvwSat);
381 if (priVars.primaryVarsMeaningWater() == PrimaryVariables::WaterMeaning::Rsw) {
382 const auto& Rsw = priVars.makeEvaluation(Indices::waterSwitchIdx,
timeIdx);
383 fluidState_.setRsw(Rsw);
385 if (FluidSystem::enableDissolvedGasInWater()) {
386 const Evaluation&
RswSat = FluidSystem::saturatedDissolutionFactor(fluidState_,
396 void updateMobilityAndInvB()
398 const unsigned pvtRegionIdx = fluidState_.pvtRegionIndex();
402 std::vector<std::array<Evaluation,numPhases>*>
mobilities = {&mobility_};
404 for (
int i=0; i<3; i++) {
406 mobilities.push_back(&(dirMob_->getArray(i)));
410 if (!FluidSystem::phaseIsActive(
phaseIdx))
412 const auto&
b = FluidSystem::inverseFormationVolumeFactor(fluidState_,
phaseIdx, pvtRegionIdx);
414 const auto&
mu = FluidSystem::viscosity(fluidState_,
phaseIdx, pvtRegionIdx);
416 if (enableExtbo &&
phaseIdx == oilPhaseIdx) {
419 else if (enableExtbo &&
phaseIdx == gasPhaseIdx) {
427 Valgrind::CheckDefined(mobility_);
430 void updatePhaseDensities()
432 const unsigned pvtRegionIdx = fluidState_.pvtRegionIndex();
436 if (FluidSystem::phaseIsActive(waterPhaseIdx)) {
437 rho = fluidState_.invB(waterPhaseIdx);
438 rho *= FluidSystem::referenceDensity(waterPhaseIdx, pvtRegionIdx);
439 if (FluidSystem::enableDissolvedGasInWater()) {
441 fluidState_.invB(waterPhaseIdx) *
443 FluidSystem::referenceDensity(gasPhaseIdx, pvtRegionIdx);
445 fluidState_.setDensity(waterPhaseIdx, rho);
448 if (FluidSystem::phaseIsActive(gasPhaseIdx)) {
449 rho = fluidState_.invB(gasPhaseIdx);
450 rho *= FluidSystem::referenceDensity(gasPhaseIdx, pvtRegionIdx);
451 if (FluidSystem::enableVaporizedOil()) {
453 fluidState_.invB(gasPhaseIdx) *
455 FluidSystem::referenceDensity(oilPhaseIdx, pvtRegionIdx);
457 if (FluidSystem::enableVaporizedWater()) {
459 fluidState_.invB(gasPhaseIdx) *
461 FluidSystem::referenceDensity(waterPhaseIdx, pvtRegionIdx);
463 fluidState_.setDensity(gasPhaseIdx, rho);
466 if (FluidSystem::phaseIsActive(oilPhaseIdx)) {
467 rho = fluidState_.invB(oilPhaseIdx);
468 rho *= FluidSystem::referenceDensity(oilPhaseIdx, pvtRegionIdx);
469 if (FluidSystem::enableDissolvedGas()) {
471 fluidState_.invB(oilPhaseIdx) *
473 FluidSystem::referenceDensity(gasPhaseIdx, pvtRegionIdx);
475 fluidState_.setDensity(oilPhaseIdx, rho);
479 void updatePorosity(
const ElementContext& elemCtx,
unsigned dofIdx,
unsigned timeIdx)
481 const auto& problem = elemCtx.problem();
482 const auto& priVars = elemCtx.primaryVars(dofIdx,
timeIdx);
483 const auto& linearizationType = problem.model().linearizer().getLinearizationType();
487 referencePorosity_ = problem.porosity(elemCtx, dofIdx,
timeIdx);
488 porosity_ = referencePorosity_;
492 Scalar rockCompressibility = problem.rockCompressibility(
globalSpaceIdx);
493 if (rockCompressibility > 0.0) {
496 if (FluidSystem::phaseIsActive(oilPhaseIdx)) {
497 x = rockCompressibility*(fluidState_.pressure(oilPhaseIdx) -
rockRefPressure);
498 }
else if (FluidSystem::phaseIsActive(waterPhaseIdx)){
499 x = rockCompressibility*(fluidState_.pressure(waterPhaseIdx) -
rockRefPressure);
501 x = rockCompressibility*(fluidState_.pressure(gasPhaseIdx) -
rockRefPressure);
503 porosity_ *= 1.0 + x + 0.5*x*x;
510 if constexpr (enableMICP){
511 Evaluation
biofilm_ = priVars.makeEvaluation(Indices::biofilmConcentrationIdx,
timeIdx, linearizationType);
512 Evaluation
calcite_ = priVars.makeEvaluation(Indices::calciteConcentrationIdx,
timeIdx, linearizationType);
517 if (enableSaltPrecipitation && priVars.primaryVarsMeaningBrine() == PrimaryVariables::BrineMeaning::Sp) {
518 Evaluation Sp = priVars.makeEvaluation(Indices::saltConcentrationIdx,
timeIdx);
519 porosity_ *= (1.0 - Sp);
523 void assertFiniteMembers()
527 if (!FluidSystem::phaseIsActive(
phaseIdx))
543 void update(
const ElementContext& elemCtx,
unsigned dofIdx,
unsigned timeIdx)
545 ParentType::update(elemCtx, dofIdx,
timeIdx);
549 const auto& problem = elemCtx.problem();
550 const auto& priVars = elemCtx.primaryVars(dofIdx,
timeIdx);
552 const unsigned pvtRegionIdx = priVars.pvtRegionIndex();
554 fluidState_.setPvtRegionIndex(pvtRegionIdx);
556 updateTempSalt(elemCtx, dofIdx,
timeIdx);
557 updateSaturations(elemCtx, dofIdx,
timeIdx);
558 updateRelpermAndPressures(elemCtx, dofIdx,
timeIdx);
561 if constexpr (enableExtbo) {
562 asImp_().zFractionUpdate_(elemCtx, dofIdx,
timeIdx);
565 Evaluation
SoMax = updateRsRvRsw(elemCtx, dofIdx,
timeIdx);
567 updateMobilityAndInvB();
568 updatePhaseDensities();
569 updatePorosity(elemCtx, dofIdx,
timeIdx);
573 if constexpr (enableSolvent) {
574 asImp_().solventPvtUpdate_(elemCtx, dofIdx,
timeIdx);
576 if constexpr (enableExtbo) {
577 asImp_().zPvtUpdate_();
579 if constexpr (enablePolymer) {
580 asImp_().polymerPropertiesUpdate_(elemCtx, dofIdx,
timeIdx);
585 if (FluidSystem::phaseIsActive(FluidSystem::oilPhaseIdx)) {
590 if constexpr (enableEnergy) {
593 if constexpr (enableFoam) {
594 asImp_().foamPropertiesUpdate_(elemCtx, dofIdx,
timeIdx);
596 if constexpr (enableMICP) {
597 asImp_().MICPPropertiesUpdate_(elemCtx, dofIdx,
timeIdx);
599 if constexpr (enableBrine) {
600 asImp_().saltPropertiesUpdate_(elemCtx, dofIdx,
timeIdx);
605 FluxIntensiveQuantities::update_(elemCtx, dofIdx,
timeIdx);
608 DiffusionIntensiveQuantities::update_(fluidState_,
paramCache, elemCtx, dofIdx,
timeIdx);
611 DispersionIntensiveQuantities::update_(elemCtx, dofIdx,
timeIdx);
614 assertFiniteMembers();
622 {
return fluidState_; }
632 using Dir = FaceDir::DirEnum;
637 return dirMob_->mobilityX_[
phaseIdx];
640 return dirMob_->mobilityY_[
phaseIdx];
643 return dirMob_->mobilityZ_[
phaseIdx];
645 throw std::runtime_error(
"Unexpected face direction");
658 {
return porosity_; }
664 {
return rockCompTransMultiplier_; }
675 {
return fluidState_.pvtRegionIndex(); }
693 {
return referencePorosity_; }
704 Implementation& asImp_()
705 {
return *
static_cast<Implementation*
>(
this); }
707 FluidState fluidState_;
708 Scalar referencePorosity_;
709 Evaluation porosity_;
710 Evaluation rockCompTransMultiplier_;
711 std::array<Evaluation,numPhases> mobility_;
728 DirectionalMobilityPtr dirMob_;