74 using FluidState =
typename IntensiveQuantities::FluidState;
76 enum { conti0EqIdx = Indices::conti0EqIdx };
81 enum { dimWorld = GridView::dimensionworld };
82 enum { gasPhaseIdx = FluidSystem::gasPhaseIdx };
83 enum { oilPhaseIdx = FluidSystem::oilPhaseIdx };
84 enum { waterPhaseIdx = FluidSystem::waterPhaseIdx };
86 enum { gasCompIdx = FluidSystem::gasCompIdx };
87 enum { oilCompIdx = FluidSystem::oilCompIdx };
88 enum { waterCompIdx = FluidSystem::waterCompIdx };
89 enum { compositionSwitchIdx = Indices::compositionSwitchIdx };
91 static constexpr bool waterEnabled = Indices::waterEnabled;
92 static constexpr bool gasEnabled = Indices::gasEnabled;
93 static constexpr bool oilEnabled = Indices::oilEnabled;
94 static constexpr bool compositionSwitchEnabled = compositionSwitchIdx >= 0;
96 static constexpr bool blackoilConserveSurfaceVolume =
109 static constexpr bool enableMICP = Indices::enableMICP;
119 using ConvectiveMixingModuleParam =
typename ConvectiveMixingModule::ConvectiveMixingModuleParam;
133 FaceDir::DirEnum faceDir;
144 ConvectiveMixingModuleParam convectiveMixingModuleParam;
150 template <
class LhsEval>
152 const ElementContext& elemCtx,
156 const IntensiveQuantities& intQuants = elemCtx.intensiveQuantities(dofIdx,
timeIdx);
160 template <
class LhsEval>
162 const IntensiveQuantities& intQuants)
166 const auto& fs = intQuants.fluidState();
170 if (!FluidSystem::phaseIsActive(
phaseIdx)) {
174 FluidSystem::canonicalToActiveCompIdx(FluidSystem::solventComponentIndex(
phaseIdx));
183 if (
phaseIdx == oilPhaseIdx && FluidSystem::enableDissolvedGas()) {
184 unsigned activeGasCompIdx = FluidSystem::canonicalToActiveCompIdx(gasCompIdx);
191 if (
phaseIdx == waterPhaseIdx && FluidSystem::enableDissolvedGasInWater()) {
192 unsigned activeGasCompIdx = FluidSystem::canonicalToActiveCompIdx(gasCompIdx);
199 if (
phaseIdx == gasPhaseIdx && FluidSystem::enableVaporizedOil()) {
200 unsigned activeOilCompIdx = FluidSystem::canonicalToActiveCompIdx(oilCompIdx);
207 if (
phaseIdx == gasPhaseIdx && FluidSystem::enableVaporizedWater()) {
218 SolventModule::addStorage(
storage, intQuants);
221 ExtboModule::addStorage(
storage, intQuants);
224 PolymerModule::addStorage(
storage, intQuants);
227 EnergyModule::addStorage(
storage, intQuants);
230 FoamModule::addStorage(
storage, intQuants);
233 BrineModule::addStorage(
storage, intQuants);
236 BioeffectsModule::addStorage(
storage, intQuants);
257 calculateFluxes_(
flux,
271 const ElementContext& elemCtx,
279 RateVector
darcy = 0.0;
281 const auto& problem = elemCtx.problem();
282 const auto& stencil = elemCtx.stencil(
timeIdx);
296 Scalar faceArea =
scvf.area();
297 const auto faceDir = faceDirFromDirId(
scvf.dirId());
303 const Scalar
g = problem.gravity()[dimWorld - 1];
323 const ResidualNBInfo res_nbinfo {
324 trans, faceArea, thpres,
distZ *
g, faceDir, Vin, Vex,
325 inAlpha, outAlpha, diffusivity, dispersivity
328 calculateFluxes_(
flux,
335 problem.moduleParams());
338 static void calculateFluxes_(RateVector&
flux,
344 const ResidualNBInfo&
nbInfo,
345 const ModuleParams& moduleParams)
348 const Scalar Vin =
nbInfo.Vin;
349 const Scalar Vex =
nbInfo.Vex;
351 const Scalar thpres =
nbInfo.thpres;
352 const Scalar trans =
nbInfo.trans;
353 const Scalar faceArea =
nbInfo.faceArea;
357 if (!FluidSystem::phaseIsActive(
phaseIdx)) {
367 Evaluation pressureDifference;
368 ExtensiveQuantities::calculatePhasePressureDiff_(
upIdx,
388 Toolbox::value(
intQuantsEx.rockCompTransMultiplier())) / 2;
389 if constexpr (enableBioeffects) {
401 FluidSystem::canonicalToActiveCompIdx(FluidSystem::solventComponentIndex(
phaseIdx));
405 unsigned pvtRegionIdx =
up.pvtRegionIndex();
412 if constexpr (enableEnergy) {
413 EnergyModule::template
416 if constexpr (enableBioeffects) {
417 BioeffectsModule::template
420 if constexpr (enableBrine) {
421 BrineModule::template
428 if constexpr (enableEnergy) {
429 EnergyModule::template
432 if constexpr (enableBioeffects) {
433 BioeffectsModule::template
436 if constexpr (enableBrine) {
437 BrineModule::template
444 static_assert(!enableSolvent,
445 "Relevant computeFlux() method must be implemented for this module before enabling.");
449 static_assert(!enableExtbo,
450 "Relevant computeFlux() method must be implemented for this module before enabling.");
454 static_assert(!enablePolymer,
455 "Relevant computeFlux() method must be implemented for this module before enabling.");
459 if constexpr (enableConvectiveMixing) {
460 ConvectiveMixingModule::addConvectiveMixingFlux(
flux,
468 moduleParams.convectiveMixingModuleParam);
472 if constexpr (enableEnergy) {
473 const Scalar inAlpha =
nbInfo.inAlpha;
474 const Scalar outAlpha =
nbInfo.outAlpha;
480 EnergyModule::ExtensiveQuantities::updateEnergy(
heatFlux,
497 static_assert(!enableFoam,
498 "Relevant computeFlux() method must be implemented for this module before enabling.");
502 if constexpr (enableDiffusion) {
503 typename DiffusionModule::ExtensiveQuantities::EvaluationArray effectiveDiffusionCoefficient;
505 const Scalar diffusivity =
nbInfo.diffusivity;
507 DiffusionModule::addDiffusiveFlux(
flux,
511 effectiveDiffusionCoefficient);
515 if constexpr (enableDispersion) {
516 typename DispersionModule::ExtensiveQuantities::ScalarArray normVelocityAvg;
518 const Scalar dispersivity =
nbInfo.dispersivity;
520 DispersionModule::addDispersiveFlux(
flux,
528 if constexpr (enableMICP) {
529 BioeffectsModule::applyScaling(
flux);
533 template <
class BoundaryConditionData>
534 static void computeBoundaryFlux(RateVector&
bdyFlux,
535 const Problem& problem,
536 const BoundaryConditionData&
bdyInfo,
548 case BCType::DIRICHLET:
551 case BCType::THERMAL:
555 throw std::logic_error(
"Unknown boundary condition type " +
556 std::to_string(
static_cast<int>(
bdyInfo.type)) +
557 " in computeBoundaryFlux()." );
561 template <
class BoundaryConditionData>
562 static void computeBoundaryFluxRate(RateVector&
bdyFlux,
563 const BoundaryConditionData&
bdyInfo)
568 template <
class BoundaryConditionData>
569 static void computeBoundaryFluxFree(
const Problem& problem,
571 const BoundaryConditionData&
bdyInfo,
576 std::array<short, numPhases>
upIdx;
577 std::array<short, numPhases>
dnIdx;
578 std::array<Evaluation, numPhases> volumeFlux;
579 std::array<Evaluation, numPhases> pressureDifference;
581 ExtensiveQuantities::calculateBoundaryGradients_(problem,
598 if (!FluidSystem::phaseIsActive(
phaseIdx)) {
618 if constexpr (enableEnergy) {
619 EnergyModule::template
624 using ScalarFluidState =
decltype(
bdyInfo.exFluidState);
633 if constexpr (enableEnergy) {
634 EnergyModule::template
639 for (
unsigned i = 0; i < tmp.size(); ++i) {
645 if constexpr (enableEnergy) {
652 EnergyModule::ExtensiveQuantities::updateEnergyBoundary(
heatFlux,
661 static_assert(!enableSolvent,
662 "Relevant treatment of boundary conditions must be implemented before enabling.");
663 static_assert(!enablePolymer,
664 "Relevant treatment of boundary conditions must be implemented before enabling.");
670 for (
unsigned i = 0; i < numEq; ++i) {
671 Valgrind::CheckDefined(
bdyFlux[i]);
673 Valgrind::CheckDefined(
bdyFlux);
677 template <
class BoundaryConditionData>
678 static void computeBoundaryThermal(
const Problem& problem,
680 const BoundaryConditionData&
bdyInfo,
689 if constexpr (enableEnergy) {
696 EnergyModule::ExtensiveQuantities::updateEnergyBoundary(
heatFlux,
706 for (
unsigned i = 0; i < numEq; ++i) {
707 Valgrind::CheckDefined(
bdyFlux[i]);
709 Valgrind::CheckDefined(
bdyFlux);
713 static void computeSource(RateVector& source,
714 const Problem& problem,
727 if constexpr (enableEnergy) {
732 static void computeSourceDense(RateVector& source,
733 const Problem& problem,
745 if constexpr (enableEnergy) {
754 const ElementContext& elemCtx,
760 elemCtx.problem().source(source, elemCtx, dofIdx,
timeIdx);
763 BioeffectsModule::addSource(source, elemCtx, dofIdx,
timeIdx);
766 if constexpr (enableEnergy) {
771 template <
class UpEval,
class Flu
idState>
772 static void evalPhaseFluxes_(RateVector&
flux,
774 unsigned pvtRegionIdx,
776 const FluidState&
upFs)
787 template <
class UpEval,
class Eval,
class Flu
idState>
790 unsigned pvtRegionIdx,
792 const FluidState&
upFs)
795 FluidSystem::canonicalToActiveCompIdx(FluidSystem::solventComponentIndex(
phaseIdx));
797 if constexpr (blackoilConserveSurfaceVolume) {
802 FluidSystem::referenceDensity(
phaseIdx, pvtRegionIdx);
807 if (FluidSystem::enableDissolvedGas()) {
808 const auto& Rs = BlackOil::getRs_<FluidSystem, FluidState, UpEval>(
upFs, pvtRegionIdx);
810 const unsigned activeGasCompIdx = FluidSystem::canonicalToActiveCompIdx(gasCompIdx);
811 if constexpr (blackoilConserveSurfaceVolume) {
817 FluidSystem::referenceDensity(gasPhaseIdx, pvtRegionIdx);
821 else if (
phaseIdx == waterPhaseIdx) {
823 if (FluidSystem::enableDissolvedGasInWater()) {
824 const auto& Rsw = BlackOil::getRsw_<FluidSystem, FluidState, UpEval>(
upFs, pvtRegionIdx);
826 const unsigned activeGasCompIdx = FluidSystem::canonicalToActiveCompIdx(gasCompIdx);
827 if constexpr (blackoilConserveSurfaceVolume) {
833 FluidSystem::referenceDensity(gasPhaseIdx, pvtRegionIdx);
839 if (FluidSystem::enableVaporizedOil()) {
840 const auto& Rv = BlackOil::getRv_<FluidSystem, FluidState, UpEval>(
upFs, pvtRegionIdx);
842 const unsigned activeOilCompIdx = FluidSystem::canonicalToActiveCompIdx(oilCompIdx);
843 if constexpr (blackoilConserveSurfaceVolume) {
849 FluidSystem::referenceDensity(oilPhaseIdx, pvtRegionIdx);
853 if (FluidSystem::enableVaporizedWater()) {
854 const auto& Rvw = BlackOil::getRvw_<FluidSystem, FluidState, UpEval>(
upFs, pvtRegionIdx);
856 const unsigned activeWaterCompIdx = FluidSystem::canonicalToActiveCompIdx(waterCompIdx);
857 if constexpr (blackoilConserveSurfaceVolume) {
863 FluidSystem::referenceDensity(waterPhaseIdx, pvtRegionIdx);
880 template <
class Scalar>
882 unsigned pvtRegionIdx)
884 if constexpr (!blackoilConserveSurfaceVolume) {
889 if constexpr (waterEnabled) {
890 const unsigned activeWaterCompIdx = FluidSystem::canonicalToActiveCompIdx(waterCompIdx);
892 FluidSystem::referenceDensity(waterPhaseIdx, pvtRegionIdx);
895 if constexpr (gasEnabled) {
896 const unsigned activeGasCompIdx = FluidSystem::canonicalToActiveCompIdx(gasCompIdx);
898 FluidSystem::referenceDensity(gasPhaseIdx, pvtRegionIdx);
901 if constexpr (oilEnabled) {
902 const unsigned activeOilCompIdx = FluidSystem::canonicalToActiveCompIdx(oilCompIdx);
904 FluidSystem::referenceDensity(oilPhaseIdx, pvtRegionIdx);
910 static FaceDir::DirEnum faceDirFromDirId(
const int dirId)
911 {
return dirId < 0 ? FaceDir::DirEnum::Unknown : FaceDir::FromIntersectionIndex(dirId); }