28 #ifndef EWOMS_BLACK_OIL_LOCAL_TPFA_RESIDUAL_HH 29 #define EWOMS_BLACK_OIL_LOCAL_TPFA_RESIDUAL_HH 31 #include <opm/input/eclipse/EclipseState/Grid/FaceDir.hpp> 32 #include <opm/input/eclipse/Schedule/BCProp.hpp> 34 #include <opm/material/common/ConditionalStorage.hpp> 35 #include <opm/material/common/MathToolbox.hpp> 36 #include <opm/material/fluidstates/BlackOilFluidState.hpp> 40 #include <opm/models/blackoil/blackoilmoduleparams.hh> 45 #include <opm/common/ErrorMacros.hpp> 46 #include <opm/common/utility/gpuDecorators.hpp> 47 #include <opm/common/utility/gpuistl_if_available.hpp> 55 #include <opm/common/utility/gpuistl_if_available.hpp> 65 template <
class TypeTag>
78 using FluidState =
typename IntensiveQuantities::FluidState;
80 enum { conti0EqIdx = Indices::conti0EqIdx };
81 enum { numEq = getPropValue<TypeTag, Properties::NumEq>() };
82 enum { numPhases = getPropValue<TypeTag, Properties::NumPhases>() };
83 enum { numComponents = getPropValue<TypeTag, Properties::NumComponents>() };
85 enum { dimWorld = GridView::dimensionworld };
86 enum { gasPhaseIdx = FluidSystem::gasPhaseIdx };
87 enum { oilPhaseIdx = FluidSystem::oilPhaseIdx };
88 enum { waterPhaseIdx = FluidSystem::waterPhaseIdx };
90 enum { gasCompIdx = FluidSystem::gasCompIdx };
91 enum { oilCompIdx = FluidSystem::oilCompIdx };
92 enum { waterCompIdx = FluidSystem::waterCompIdx };
93 static constexpr
unsigned compositionSwitchIdx = Indices::compositionSwitchIdx;
95 static constexpr
bool waterEnabled = Indices::waterEnabled;
96 static constexpr
bool gasEnabled = Indices::gasEnabled;
97 static constexpr
bool oilEnabled = Indices::oilEnabled;
98 static constexpr
bool compositionSwitchEnabled =
99 compositionSwitchIdx != std::numeric_limits<unsigned>::max();
101 static constexpr
bool blackoilConserveSurfaceVolume
102 = getPropValue<TypeTag, Properties::BlackoilConserveSurfaceVolume>();
104 static constexpr
bool enableSolvent = getPropValue<TypeTag, Properties::EnableSolvent>();
105 static constexpr
bool enableExtbo = getPropValue<TypeTag, Properties::EnableExtbo>();
106 static constexpr
bool enablePolymer = getPropValue<TypeTag, Properties::EnablePolymer>();
107 static constexpr EnergyModules energyModuleType =
108 getPropValue<TypeTag, Properties::EnergyModuleType>();
109 static constexpr
bool enableFullyImplicitThermal =
110 energyModuleType == EnergyModules::FullyImplicitThermal;
111 static constexpr
bool enableFoam = getPropValue<TypeTag, Properties::EnableFoam>();
112 static constexpr
bool enableBrine = getPropValue<TypeTag, Properties::EnableBrine>();
113 static constexpr
bool enableDiffusion = getPropValue<TypeTag, Properties::EnableDiffusion>();
114 static constexpr
bool enableDispersion = getPropValue<TypeTag, Properties::EnableDispersion>();
115 static constexpr
bool enableConvectiveMixing
116 = getPropValue<TypeTag, Properties::EnableConvectiveMixing>();
117 static constexpr
bool enableBioeffects = getPropValue<TypeTag, Properties::EnableBioeffects>();
118 static constexpr
bool enableSaltPrecipitation
119 = getPropValue<TypeTag, Properties::EnableSaltPrecipitation>();
120 static constexpr
bool enableMICP = Indices::enableMICP;
121 static constexpr
bool runAssemblyOnGpu = getPropValue<TypeTag, Properties::RunAssemblyOnGpu>();
123 using BioeffectsModule = BlackOilBioeffectsModule<TypeTag, enableBioeffects>;
124 using BrineModule = BlackOilBrineModule<TypeTag, enableBrine>;
125 using ConvectiveMixingModule = BlackOilConvectiveMixingModule<TypeTag, enableConvectiveMixing>;
129 using ExtboModule = BlackOilExtboModule<TypeTag, enableExtbo>;
131 using SolventModule = BlackOilSolventModule<TypeTag, enableSolvent>;
132 using PolymerModule = BlackOilPolymerModule<TypeTag, enablePolymer>;
135 using Toolbox = MathToolbox<Evaluation>;
144 FaceDir::DirEnum faceDir;
147 ConditionalStorage<enableFullyImplicitThermal, double> inAlpha;
148 ConditionalStorage<enableFullyImplicitThermal, double> outAlpha;
149 ConditionalStorage<enableDiffusion, double> diffusivity;
150 ConditionalStorage<enableDispersion, double> dispersivity;
156 template <
class LhsEval>
158 const ElementContext& elemCtx,
160 unsigned timeIdx)
const 162 const IntensiveQuantities& intQuants = elemCtx.intensiveQuantities(dofIdx, timeIdx);
163 computeStorage<LhsEval>(storage, intQuants);
166 template <
class LhsEval,
class StorageType,
class IntensiveQuantitiesType = IntensiveQuantities>
168 const IntensiveQuantitiesType& intQuants)
172 const auto& fs = intQuants.fluidState();
175 const FluidSystem& fsys = intQuants.getFluidSystem();
177 for (
unsigned phaseIdx = 0; phaseIdx < numPhases; ++phaseIdx) {
178 if (!fsys.phaseIsActive(phaseIdx)) {
181 unsigned activeCompIdx
182 = fsys.canonicalToActiveCompIdx(fsys.solventComponentIndex(phaseIdx));
183 LhsEval surfaceVolume = Toolbox::template decay<LhsEval>(fs.saturation(phaseIdx))
184 * Toolbox::template decay<LhsEval>(fs.invB(phaseIdx))
185 * Toolbox::template decay<LhsEval>(intQuants.porosity());
187 storage[conti0EqIdx + activeCompIdx] += surfaceVolume;
190 if (phaseIdx == oilPhaseIdx && fsys.enableDissolvedGas()) {
191 unsigned activeGasCompIdx = fsys.canonicalToActiveCompIdx(gasCompIdx);
192 storage[conti0EqIdx + activeGasCompIdx]
193 += Toolbox::template decay<LhsEval>(intQuants.fluidState().Rs())
198 if (phaseIdx == waterPhaseIdx && fsys.enableDissolvedGasInWater()) {
199 unsigned activeGasCompIdx = fsys.canonicalToActiveCompIdx(gasCompIdx);
200 storage[conti0EqIdx + activeGasCompIdx]
201 += Toolbox::template decay<LhsEval>(intQuants.fluidState().Rsw())
206 if (phaseIdx == gasPhaseIdx && fsys.enableVaporizedOil()) {
207 unsigned activeOilCompIdx = fsys.canonicalToActiveCompIdx(oilCompIdx);
208 storage[conti0EqIdx + activeOilCompIdx]
209 += Toolbox::template decay<LhsEval>(intQuants.fluidState().Rv())
214 if (phaseIdx == gasPhaseIdx && fsys.enableVaporizedWater()) {
215 unsigned activeWaterCompIdx = fsys.canonicalToActiveCompIdx(waterCompIdx);
216 storage[conti0EqIdx + activeWaterCompIdx]
217 += Toolbox::template decay<LhsEval>(intQuants.fluidState().Rvw())
225 if constexpr (enableSolvent) {
226 SolventModule::addStorage(storage, intQuants);
230 if constexpr (enableExtbo) {
231 ExtboModule::addStorage(storage, intQuants);
235 if constexpr (enablePolymer) {
236 PolymerModule::addStorage(storage, intQuants);
240 if constexpr (enableFullyImplicitThermal) {
241 EnergyModule::addStorage(storage, intQuants);
245 if constexpr (enableFoam) {
246 FoamModule::addStorage(storage, intQuants);
250 if constexpr (enableBrine) {
251 BrineModule::addStorage(storage, intQuants);
255 if constexpr (enableBioeffects) {
256 BioeffectsModule::addStorage(storage, intQuants);
265 template <
class ModuleParamsT,
267 class IntensiveQuantitiesT,
268 class ResidualNBInfoT>
271 const unsigned globalIndexIn,
272 const unsigned globalIndexEx,
273 const IntensiveQuantitiesT& intQuantsIn,
274 const IntensiveQuantitiesT& intQuantsEx,
275 const ResidualNBInfoT& nbInfo,
276 const ModuleParamsT& moduleParams)
278 OPM_TIMEBLOCK_LOCAL(
computeFlux, Subsystem::Assembly);
282 calculateFluxes_(flux,
296 computeFlux(RateVector& flux,
const ElementContext& elemCtx,
unsigned scvfIdx,
unsigned timeIdx)
298 OPM_TIMEBLOCK_LOCAL(
computeFlux, Subsystem::Assembly);
299 assert(timeIdx == 0);
302 RateVector darcy = 0.0;
304 const auto& problem = elemCtx.problem();
305 const auto& stencil = elemCtx.stencil(timeIdx);
306 const auto& scvf = stencil.interiorFace(scvfIdx);
308 unsigned interiorDofIdx = scvf.interiorIndex();
309 unsigned exteriorDofIdx = scvf.exteriorIndex();
310 assert(interiorDofIdx != exteriorDofIdx);
314 Scalar Vin = elemCtx.dofVolume(interiorDofIdx, 0);
315 Scalar Vex = elemCtx.dofVolume(exteriorDofIdx, 0);
316 const auto& globalIndexIn = stencil.globalSpaceIndex(interiorDofIdx);
317 const auto& globalIndexEx = stencil.globalSpaceIndex(exteriorDofIdx);
318 Scalar trans = problem.transmissibility(elemCtx, interiorDofIdx, exteriorDofIdx);
319 Scalar faceArea = scvf.area();
320 const auto faceDir = faceDirFromDirId(scvf.dirId());
321 Scalar thpresInToEx = problem.thresholdPressure(globalIndexIn, globalIndexEx);
322 Scalar thpresExToIn = problem.thresholdPressure(globalIndexEx, globalIndexIn);
327 const Scalar g = problem.gravity()[dimWorld - 1];
328 const auto& intQuantsIn = elemCtx.intensiveQuantities(interiorDofIdx, timeIdx);
329 const auto& intQuantsEx = elemCtx.intensiveQuantities(exteriorDofIdx, timeIdx);
336 const Scalar zIn = problem.dofCenterDepth(elemCtx, interiorDofIdx, timeIdx);
337 const Scalar zEx = problem.dofCenterDepth(elemCtx, exteriorDofIdx, timeIdx);
340 const Scalar distZ = zIn - zEx;
342 const Scalar inAlpha = problem.thermalHalfTransmissibility(globalIndexIn, globalIndexEx);
343 const Scalar outAlpha = problem.thermalHalfTransmissibility(globalIndexEx, globalIndexIn);
344 const Scalar diffusivity = problem.diffusivity(globalIndexEx, globalIndexIn);
345 const Scalar dispersivity = problem.dispersivity(globalIndexEx, globalIndexIn);
347 const ResidualNBInfo res_nbinfo {trans,
360 calculateFluxes_(flux,
367 problem.moduleParams());
370 template <
class RateVectorT,
371 class IntensiveQuantitiesT,
372 class ResidualNBInfoT,
374 OPM_HOST_DEVICE
static void calculateFluxes_(RateVectorT& flux,
376 const IntensiveQuantitiesT& intQuantsIn,
377 const IntensiveQuantitiesT& intQuantsEx,
378 const unsigned& globalIndexIn,
379 const unsigned& globalIndexEx,
380 const ResidualNBInfoT& nbInfo,
381 const ModuleParamsT& moduleParams)
383 OPM_TIMEBLOCK_LOCAL(calculateFluxes, Subsystem::Assembly);
384 const Scalar Vin = nbInfo.Vin;
385 const Scalar Vex = nbInfo.Vex;
386 const Scalar distZg = nbInfo.dZg;
387 const Scalar thpresInToEx = nbInfo.thpresInToEx;
388 const Scalar thpresExToIn = nbInfo.thpresExToIn;
389 const Scalar trans = nbInfo.trans;
390 const Scalar faceArea = nbInfo.faceArea;
391 FaceDir::DirEnum facedir = nbInfo.faceDir;
393 const FluidSystem& fsys = intQuantsIn.getFluidSystem();
395 for (
unsigned phaseIdx = 0; phaseIdx < numPhases; ++phaseIdx) {
396 if (!fsys.phaseIsActive(phaseIdx)) {
404 short interiorDofIdx = 0;
405 short exteriorDofIdx = 1;
406 Evaluation pressureDifference;
407 ExtensiveQuantities::calculatePhasePressureDiff_(upIdx,
424 const IntensiveQuantities& up = (upIdx == interiorDofIdx) ? intQuantsIn : intQuantsEx;
425 unsigned globalUpIndex = (upIdx == interiorDofIdx) ? globalIndexIn : globalIndexEx;
428 Evaluation transMult = (intQuantsIn.rockCompTransMultiplier()
429 + Toolbox::value(intQuantsEx.rockCompTransMultiplier()))
431 if constexpr (enableBioeffects || enableSaltPrecipitation) {
433 *= (intQuantsIn.permFactor() + Toolbox::value(intQuantsEx.permFactor())) / 2;
436 Evaluation darcyFlux;
437 if (globalUpIndex == globalIndexIn) {
438 darcyFlux = pressureDifference * up.mobility(phaseIdx, facedir) * transMult
439 * (-trans / faceArea);
441 darcyFlux = pressureDifference
442 * (Toolbox::value(up.mobility(phaseIdx, facedir)) * transMult
443 * (-trans / faceArea));
446 unsigned activeCompIdx
447 = fsys.canonicalToActiveCompIdx(fsys.solventComponentIndex(phaseIdx));
449 darcy[conti0EqIdx + activeCompIdx] = darcyFlux.value() * faceArea;
451 unsigned pvtRegionIdx = up.pvtRegionIndex();
453 if (globalUpIndex == globalIndexIn) {
454 const auto& invB = getInvB_<FluidSystem, FluidState, Evaluation>(
455 up.fluidState(), phaseIdx, pvtRegionIdx, fsys);
456 const auto& surfaceVolumeFlux = invB * darcyFlux;
458 evalPhaseFluxes_<Evaluation>(
459 flux, phaseIdx, pvtRegionIdx, surfaceVolumeFlux, up.fluidState());
460 if constexpr (enableFullyImplicitThermal) {
461 EnergyModule::template addPhaseEnthalpyFluxes_<Evaluation>(
462 flux, phaseIdx, darcyFlux, up.fluidState());
464 if constexpr (enableBioeffects) {
465 BioeffectsModule::template addBioeffectsFluxes_<Evaluation>(
466 flux, phaseIdx, darcyFlux, up);
468 if constexpr (enableBrine) {
469 BrineModule::template addBrineFluxes_<Evaluation, FluidState>(
470 flux, phaseIdx, darcyFlux, up.fluidState());
473 const auto& invB = getInvB_<FluidSystem, FluidState, Scalar>(
474 up.fluidState(), phaseIdx, pvtRegionIdx, fsys);
475 const auto& surfaceVolumeFlux = invB * darcyFlux;
476 evalPhaseFluxes_<Scalar>(
477 flux, phaseIdx, pvtRegionIdx, surfaceVolumeFlux, up.fluidState());
478 if constexpr (enableFullyImplicitThermal) {
479 EnergyModule::template addPhaseEnthalpyFluxes_<Scalar>(
480 flux, phaseIdx, darcyFlux, up.fluidState());
482 if constexpr (enableBioeffects) {
483 BioeffectsModule::template addBioeffectsFluxes_<Scalar>(
484 flux, phaseIdx, darcyFlux, up);
486 if constexpr (enableBrine) {
487 BrineModule::template addBrineFluxes_<Scalar, FluidState>(
488 flux, phaseIdx, darcyFlux, up.fluidState());
496 "Relevant computeFlux() method must be implemented for this module before enabling.");
502 "Relevant computeFlux() method must be implemented for this module before enabling.");
508 "Relevant computeFlux() method must be implemented for this module before enabling.");
512 if constexpr (enableConvectiveMixing) {
513 ConvectiveMixingModule::addConvectiveMixingFlux(
522 moduleParams.convectiveMixingModuleParam);
526 if constexpr (enableFullyImplicitThermal) {
527 const Scalar inAlpha = nbInfo.inAlpha;
528 const Scalar outAlpha = nbInfo.outAlpha;
531 short interiorDofIdx = 0;
532 short exteriorDofIdx = 1;
534 EnergyModule::ExtensiveQuantities::updateEnergy(heatFlux,
540 intQuantsIn.fluidState(),
541 intQuantsEx.fluidState(),
545 EnergyModule::addHeatFlux(flux, heatFlux);
553 "Relevant computeFlux() method must be implemented for this module before enabling.");
558 if constexpr (enableDiffusion) {
559 typename DiffusionModule::ExtensiveQuantities::EvaluationArray
560 effectiveDiffusionCoefficient;
561 DiffusionModule::ExtensiveQuantities::update(
562 effectiveDiffusionCoefficient, intQuantsIn, intQuantsEx);
563 const Scalar diffusivity = nbInfo.diffusivity;
564 const Scalar tmpdiffusivity = diffusivity / faceArea;
565 DiffusionModule::addDiffusiveFlux(
566 flux, intQuantsIn, intQuantsEx, tmpdiffusivity, effectiveDiffusionCoefficient);
571 if constexpr (enableDispersion) {
572 typename DispersionModule::ExtensiveQuantities::ScalarArray normVelocityAvg;
573 DispersionModule::ExtensiveQuantities::update(
574 normVelocityAvg, intQuantsIn, intQuantsEx);
575 const Scalar dispersivity = nbInfo.dispersivity;
576 const Scalar tmpdispersivity = dispersivity / faceArea;
577 DispersionModule::addDispersiveFlux(
578 flux, intQuantsIn, intQuantsEx, tmpdispersivity, normVelocityAvg);
582 if constexpr (enableMICP) {
583 BioeffectsModule::applyScaling(flux);
587 template <
class BoundaryConditionData>
588 static void computeBoundaryFluxRate(RateVector& bdyFlux,
const BoundaryConditionData& bdyInfo)
590 bdyFlux.setMassRate(bdyInfo.massRate, bdyInfo.pvtRegionIdx);
593 template <
class BoundaryConditionData>
594 static void computeBoundaryFluxFree(
const Problem& problem,
596 const BoundaryConditionData& bdyInfo,
597 const IntensiveQuantities& insideIntQuants,
598 unsigned globalSpaceIdx)
600 OPM_TIMEBLOCK_LOCAL(computeBoundaryFluxFree, Subsystem::Assembly);
601 std::array<short, numPhases> upIdx;
602 std::array<short, numPhases> dnIdx;
603 std::array<Evaluation, numPhases> volumeFlux;
604 std::array<Evaluation, numPhases> pressureDifference;
606 ExtensiveQuantities::calculateBoundaryGradients_(problem,
609 bdyInfo.boundaryFaceIndex,
612 bdyInfo.exFluidState,
622 for (
unsigned phaseIdx = 0; phaseIdx < numPhases; ++phaseIdx) {
623 if (!FluidSystem::phaseIsActive(phaseIdx)) {
626 const auto& pBoundary = bdyInfo.exFluidState.pressure(phaseIdx);
627 const Evaluation& pInside = insideIntQuants.fluidState().pressure(phaseIdx);
628 const unsigned pvtRegionIdx = insideIntQuants.pvtRegionIndex();
631 const auto& darcyFlux = volumeFlux[phaseIdx];
633 if (pBoundary < pInside) {
635 const auto& invB = getInvB_<FluidSystem, FluidState, Evaluation>(
636 insideIntQuants.fluidState(), phaseIdx, pvtRegionIdx);
637 Evaluation surfaceVolumeFlux = invB * darcyFlux;
638 evalPhaseFluxes_<Evaluation>(tmp,
640 insideIntQuants.pvtRegionIndex(),
642 insideIntQuants.fluidState());
643 if constexpr (enableFullyImplicitThermal) {
644 EnergyModule::template addPhaseEnthalpyFluxes_<Evaluation>(
645 tmp, phaseIdx, darcyFlux, insideIntQuants.fluidState());
647 }
else if (pBoundary > pInside) {
649 using ScalarFluidState = decltype(bdyInfo.exFluidState);
650 const auto& invB = getInvB_<FluidSystem, ScalarFluidState, Scalar>(
651 bdyInfo.exFluidState, phaseIdx, pvtRegionIdx);
652 Evaluation surfaceVolumeFlux = invB * darcyFlux;
653 evalPhaseFluxes_<Scalar>(tmp,
655 insideIntQuants.pvtRegionIndex(),
657 bdyInfo.exFluidState);
658 if constexpr (enableFullyImplicitThermal) {
659 EnergyModule::template addPhaseEnthalpyFluxes_<Scalar>(
660 tmp, phaseIdx, darcyFlux, bdyInfo.exFluidState);
664 for (
unsigned i = 0; i < tmp.size(); ++i) {
665 bdyFlux[i] += tmp[i];
670 if constexpr (enableFullyImplicitThermal) {
673 Scalar alpha = problem.eclTransmissibilities().thermalHalfTransBoundary(
674 globalSpaceIdx, bdyInfo.boundaryFaceIndex);
677 EnergyModule::ExtensiveQuantities::updateEnergyBoundary(heatFlux,
682 bdyInfo.exFluidState);
683 EnergyModule::addHeatFlux(bdyFlux, heatFlux);
688 "Relevant treatment of boundary conditions must be implemented before enabling.");
691 "Relevant treatment of boundary conditions must be implemented before enabling.");
693 const FluidSystem& fsys = insideIntQuants.getFluidSystem();
699 for (
unsigned i = 0; i < numEq; ++i) {
700 Valgrind::CheckDefined(bdyFlux[i]);
702 Valgrind::CheckDefined(bdyFlux);
706 template <
class ProblemLocal,
class BoundaryConditionData,
class RateVectorLocal>
707 OPM_HOST_DEVICE
static void computeBoundaryThermal(
const ProblemLocal& problem,
708 RateVectorLocal& bdyFlux,
709 const BoundaryConditionData& bdyInfo,
710 const IntensiveQuantities& insideIntQuants,
711 [[maybe_unused]]
unsigned globalSpaceIdx)
713 OPM_TIMEBLOCK_LOCAL(computeBoundaryThermal, Subsystem::Assembly);
718 if constexpr (enableFullyImplicitThermal) {
722 if constexpr (!std::is_empty_v<GetPropType<TypeTag, Properties::FluidSystem>>) {
723 alpha = problem.getAlpha(globalSpaceIdx, bdyInfo.boundaryFaceIndex);
725 alpha = problem.eclTransmissibilities().thermalHalfTransBoundary(globalSpaceIdx, bdyInfo.boundaryFaceIndex);
729 EnergyModule::ExtensiveQuantities::updateEnergyBoundary(heatFlux,
734 bdyInfo.exFluidState);
735 EnergyModule::addHeatFlux(bdyFlux, heatFlux);
739 for (
unsigned i = 0; i < numEq; ++i) {
740 Valgrind::CheckDefined(bdyFlux[i]);
742 Valgrind::CheckDefined(bdyFlux);
746 template <
class BoundaryConditionData,
class RateVectorLocal,
class LocalProblem>
747 OPM_HOST_DEVICE
static void computeBoundaryFlux(RateVectorLocal& bdyFlux,
748 const LocalProblem& problem,
749 const BoundaryConditionData& bdyInfo,
750 const IntensiveQuantities& insideIntQuants,
751 unsigned globalSpaceIdx)
753 if constexpr (std::is_empty_v<GetPropType<TypeTag, Properties::FluidSystem>>) {
754 switch (bdyInfo.type) {
759 computeBoundaryFluxRate(bdyFlux, bdyInfo);
762 case BCType::DIRICHLET:
763 computeBoundaryFluxFree(problem, bdyFlux, bdyInfo, insideIntQuants, globalSpaceIdx);
765 case BCType::THERMAL:
766 computeBoundaryThermal(problem, bdyFlux, bdyInfo, insideIntQuants, globalSpaceIdx);
769 OPM_THROW(std::logic_error,
"Unknown boundary condition type " 770 + std::to_string(static_cast<int>(bdyInfo.type))
771 +
" in computeBoundaryFlux().");
774 switch (bdyInfo.type) {
778 case BCType::THERMAL:
779 computeBoundaryThermal(problem, bdyFlux, bdyInfo, insideIntQuants, globalSpaceIdx);
782 OPM_THROW(std::logic_error,
783 "Boundary condition type " + std::to_string(static_cast<int>(bdyInfo.type))
784 +
" is not supported for GPU fluid systems in computeBoundaryFlux().");
789 static void computeSource(RateVector& source,
790 const Problem& problem,
791 const IntensiveQuantities& insideIntQuants,
792 unsigned globalSpaceIdex,
795 OPM_TIMEBLOCK_LOCAL(computeSource, Subsystem::Assembly);
797 problem.source(source, globalSpaceIdex, timeIdx);
800 if constexpr (enableBioeffects) {
801 BioeffectsModule::addSource(source, problem, insideIntQuants, globalSpaceIdex);
805 if constexpr (enableFullyImplicitThermal) {
806 source[Indices::contiEnergyEqIdx]
807 *= getPropValue<TypeTag, Properties::BlackOilEnergyScalingFactor>();
811 static void computeSourceDense(RateVector& source,
812 const Problem& problem,
813 const IntensiveQuantities& insideIntQuants,
814 unsigned globalSpaceIdex,
818 problem.addToSourceDense(source, globalSpaceIdex, timeIdx);
821 if constexpr (enableBioeffects) {
822 BioeffectsModule::addSource(source, problem, insideIntQuants, globalSpaceIdex);
826 if constexpr (enableFullyImplicitThermal) {
827 source[Indices::contiEnergyEqIdx]
828 *= getPropValue<TypeTag, Properties::BlackOilEnergyScalingFactor>();
836 const ElementContext& elemCtx,
838 unsigned timeIdx)
const 840 OPM_TIMEBLOCK_LOCAL(computeSource, Subsystem::Assembly);
842 elemCtx.problem().source(source, elemCtx, dofIdx, timeIdx);
845 if constexpr (enableBioeffects) {
846 BioeffectsModule::addSource(source, elemCtx, dofIdx, timeIdx);
850 if constexpr (enableFullyImplicitThermal) {
851 source[Indices::contiEnergyEqIdx]
852 *= getPropValue<TypeTag, Properties::BlackOilEnergyScalingFactor>();
856 template <
class UpEval,
class Flu
idState>
857 static void evalPhaseFluxes_(RateVector& flux,
859 unsigned pvtRegionIdx,
860 const ExtensiveQuantities& extQuants,
861 const FluidState& upFs)
863 const auto& invB = getInvB_<FluidSystem, FluidState, UpEval>(upFs, phaseIdx, pvtRegionIdx);
864 const auto& surfaceVolumeFlux = invB * extQuants.volumeFlux(phaseIdx);
865 evalPhaseFluxes_<UpEval>(flux, phaseIdx, pvtRegionIdx, surfaceVolumeFlux, upFs);
872 template <
class UpEval,
class Eval,
class Flu
idState,
class RateVectorT = RateVector>
875 unsigned pvtRegionIdx,
876 const Eval& surfaceVolumeFlux,
877 const FluidState& upFs)
879 const FluidSystem& fsys = upFs.fluidSystem();
881 unsigned activeCompIdx
882 = fsys.canonicalToActiveCompIdx(fsys.solventComponentIndex(phaseIdx));
884 if constexpr (blackoilConserveSurfaceVolume) {
885 flux[conti0EqIdx + activeCompIdx] += surfaceVolumeFlux;
887 flux[conti0EqIdx + activeCompIdx]
888 += surfaceVolumeFlux * fsys.referenceDensity(phaseIdx, pvtRegionIdx);
891 if (phaseIdx == oilPhaseIdx) {
893 if (fsys.enableDissolvedGas()) {
895 = BlackOil::getRs_<FluidSystem, FluidState, UpEval>(upFs, pvtRegionIdx);
897 const unsigned activeGasCompIdx = fsys.canonicalToActiveCompIdx(gasCompIdx);
898 if constexpr (blackoilConserveSurfaceVolume) {
899 flux[conti0EqIdx + activeGasCompIdx] += Rs * surfaceVolumeFlux;
901 flux[conti0EqIdx + activeGasCompIdx] += Rs * surfaceVolumeFlux
902 * fsys.referenceDensity(gasPhaseIdx, pvtRegionIdx);
905 }
else if (phaseIdx == waterPhaseIdx) {
907 if (fsys.enableDissolvedGasInWater()) {
909 = BlackOil::getRsw_<FluidSystem, FluidState, UpEval>(upFs, pvtRegionIdx);
911 const unsigned activeGasCompIdx = fsys.canonicalToActiveCompIdx(gasCompIdx);
912 if constexpr (blackoilConserveSurfaceVolume) {
913 flux[conti0EqIdx + activeGasCompIdx] += Rsw * surfaceVolumeFlux;
915 flux[conti0EqIdx + activeGasCompIdx] += Rsw * surfaceVolumeFlux
916 * fsys.referenceDensity(gasPhaseIdx, pvtRegionIdx);
919 }
else if (phaseIdx == gasPhaseIdx) {
921 if (fsys.enableVaporizedOil()) {
923 = BlackOil::getRv_<FluidSystem, FluidState, UpEval>(upFs, pvtRegionIdx);
925 const unsigned activeOilCompIdx = fsys.canonicalToActiveCompIdx(oilCompIdx);
926 if constexpr (blackoilConserveSurfaceVolume) {
927 flux[conti0EqIdx + activeOilCompIdx] += Rv * surfaceVolumeFlux;
929 flux[conti0EqIdx + activeOilCompIdx] += Rv * surfaceVolumeFlux
930 * fsys.referenceDensity(oilPhaseIdx, pvtRegionIdx);
934 if (fsys.enableVaporizedWater()) {
936 = BlackOil::getRvw_<FluidSystem, FluidState, UpEval>(upFs, pvtRegionIdx);
938 const unsigned activeWaterCompIdx = fsys.canonicalToActiveCompIdx(waterCompIdx);
939 if constexpr (blackoilConserveSurfaceVolume) {
940 flux[conti0EqIdx + activeWaterCompIdx] += Rvw * surfaceVolumeFlux;
942 flux[conti0EqIdx + activeWaterCompIdx] += Rvw * surfaceVolumeFlux
943 * fsys.referenceDensity(waterPhaseIdx, pvtRegionIdx);
952 template <
class ScalarVector>
954 unsigned pvtRegionIdx)
975 template <
class ScalarVector,
class FsysType>
977 unsigned pvtRegionIdx,
978 const FsysType& fsys)
980 if constexpr (!blackoilConserveSurfaceVolume) {
985 if constexpr (waterEnabled) {
986 const unsigned activeWaterCompIdx = fsys.canonicalToActiveCompIdx(waterCompIdx);
987 container[conti0EqIdx + activeWaterCompIdx]
988 *= fsys.referenceDensity(waterPhaseIdx, pvtRegionIdx);
991 if constexpr (gasEnabled) {
992 const unsigned activeGasCompIdx = fsys.canonicalToActiveCompIdx(gasCompIdx);
993 container[conti0EqIdx + activeGasCompIdx]
994 *= fsys.referenceDensity(gasPhaseIdx, pvtRegionIdx);
997 if constexpr (oilEnabled) {
998 const unsigned activeOilCompIdx = fsys.canonicalToActiveCompIdx(oilCompIdx);
999 container[conti0EqIdx + activeOilCompIdx]
1000 *= fsys.referenceDensity(oilPhaseIdx, pvtRegionIdx);
1006 static FaceDir::DirEnum faceDirFromDirId(
const int dirId)
1008 return dirId < 0 ? FaceDir::DirEnum::Unknown : FaceDir::FromIntersectionIndex(dirId);
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: blackoilfoammodules.hh:57
Calculates the local residual of the black oil model.
Definition: blackoillocalresidualtpfa.hh:66
static OPM_HOST_DEVICE void adaptMassConservationQuantities_(ScalarVector &container, unsigned pvtRegionIdx)
Wrapper of adaptMassConservationQuantities_ that does not take a fluid system instance.
Definition: blackoillocalresidualtpfa.hh:953
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.
Definition: blackoilmodules.hpp:62
Classes required for dynamic convective mixing.
Declares the properties required by the black oil model.
Declare the properties used by the infrastructure code of the finite volume discretizations.
static OPM_HOST_DEVICE void computeFlux(RateVectorT &flux, RateVectorT &darcy, const unsigned globalIndexIn, const unsigned globalIndexEx, const IntensiveQuantitiesT &intQuantsIn, const IntensiveQuantitiesT &intQuantsEx, const ResidualNBInfoT &nbInfo, const ModuleParamsT &moduleParams)
This function works like the ElementContext-based version with one main difference: The darcy flux is...
Definition: blackoillocalresidualtpfa.hh:269
Definition: blackoillocalresidualtpfa.hh:138
static OPM_HOST_DEVICE void evalPhaseFluxes_(RateVectorT &flux, unsigned phaseIdx, unsigned pvtRegionIdx, const Eval &surfaceVolumeFlux, const FluidState &upFs)
Helper function to calculate the flux of mass in terms of conservation quantities via specific fluid ...
Definition: blackoillocalresidualtpfa.hh:873
void computeStorage(Dune::FieldVector< LhsEval, numEq > &storage, const ElementContext &elemCtx, unsigned dofIdx, unsigned timeIdx) const
Evaluate the amount all conservation quantities (e.g.
Definition: blackoillocalresidualtpfa.hh:157
Provides the auxiliary methods required for consideration of the dispersion equation.
void computeSource(RateVector &source, const ElementContext &elemCtx, unsigned dofIdx, unsigned timeIdx) const
Calculate the source term of the equation.
Definition: blackoillocalresidualtpfa.hh:835
static OPM_HOST_DEVICE void adaptMassConservationQuantities_(ScalarVector &container, unsigned pvtRegionIdx, const FsysType &fsys)
Helper function to convert the mass-related parts of a vector that stores conservation quantities in ...
Definition: blackoillocalresidualtpfa.hh:976
Provides the auxiliary methods required for consideration of the diffusion equation.