106 using Toolbox = MathToolbox<Evaluation>;
108 using TabulatedFunction =
typename BlackOilBioeffectsParams<Scalar>::TabulatedFunction;
110 enum { gasCompIdx = FluidSystem::gasCompIdx };
112 static constexpr unsigned microbialConcentrationIdx = Indices::microbialConcentrationIdx;
113 static constexpr unsigned oxygenConcentrationIdx = Indices::oxygenConcentrationIdx;
114 static constexpr unsigned ureaConcentrationIdx = Indices::ureaConcentrationIdx;
115 static constexpr unsigned biofilmVolumeFractionIdx = Indices::biofilmVolumeFractionIdx;
116 static constexpr unsigned calciteVolumeFractionIdx = Indices::calciteVolumeFractionIdx;
117 static constexpr unsigned contiMicrobialEqIdx = Indices::contiMicrobialEqIdx;
118 static constexpr unsigned contiOxygenEqIdx = Indices::contiOxygenEqIdx;
119 static constexpr unsigned contiUreaEqIdx = Indices::contiUreaEqIdx;
120 static constexpr unsigned contiBiofilmEqIdx = Indices::contiBiofilmEqIdx;
121 static constexpr unsigned contiCalciteEqIdx = Indices::contiCalciteEqIdx;
122 static constexpr unsigned waterPhaseIdx = FluidSystem::waterPhaseIdx;
124 static constexpr unsigned enableBioeffects = enableBioeffectsV;
125 static constexpr bool enableMICP = Indices::enableMICP;
141 if constexpr (enableBioeffects)
149 Simulator& simulator)
151 if constexpr (enableBioeffects)
155 static bool eqApplies(
unsigned eqIdx)
157 if constexpr (enableBioeffects)
158 if constexpr (enableMICP)
159 return eqIdx == contiMicrobialEqIdx ||
eqIdx == contiOxygenEqIdx ||
eqIdx == contiUreaEqIdx
160 ||
eqIdx == contiBiofilmEqIdx ||
eqIdx == contiCalciteEqIdx;
162 return eqIdx == contiMicrobialEqIdx ||
eqIdx == contiBiofilmEqIdx;
172 return static_cast<Scalar
>(1.0);
176 template <
class LhsEval>
177 static void addStorage(Dune::FieldVector<LhsEval, numEq>&
storage,
178 const IntensiveQuantities& intQuants)
180 if constexpr (enableBioeffects) {
181 const auto& fs = intQuants.fluidState();
193 if constexpr (enableMICP) {
208 template <
class UpEval>
209 static void addBioeffectsFluxes_(RateVector&
flux,
211 const Evaluation& volumeFlux,
212 const IntensiveQuantities&
upFs)
215 if constexpr (enableBioeffects) {
216 flux[contiMicrobialEqIdx] =
220 if constexpr (enableMICP) {
221 flux[contiOxygenEqIdx] =
225 flux[contiUreaEqIdx] =
235 static void applyScaling(RateVector&
flux)
237 if constexpr (enableMICP) {
247 if constexpr (enableBioeffects) {
249 unsigned focusIdx = elemCtx.focusDofIndex();
251 flux[contiMicrobialEqIdx] = 0.0;
252 if constexpr (enableMICP) {
253 flux[contiOxygenEqIdx] = 0.0;
254 flux[contiUreaEqIdx] = 0.0;
263 template <
class UpstreamEval>
264 static void addBioeffectsFluxes_(RateVector&
flux,
265 const ElementContext& elemCtx,
276 static void addSource(RateVector& source,
277 const Problem& problem,
278 const IntensiveQuantities& intQuants,
281 if constexpr (enableBioeffects) {
282 const auto b = intQuants.fluidState().invB(waterPhaseIdx);
288 Scalar Y = yieldGrowthCoefficient(
satnumIdx);
292 const auto&
velocityInf = problem.model().linearizer().getVelocityInfo();
294 Scalar normVelocityCell =
296 [](
const auto acc,
const auto& info)
297 { return max(acc, std::abs(info.velocity[waterPhaseIdx])); });
298 if constexpr (enableMICP) {
302 Scalar F = oxygenConsumptionFactor(
satnumIdx);
307 Evaluation
k_g =
mu * intQuants.oxygenConcentration() / (
k_n + intQuants.oxygenConcentration());
308 Evaluation
k_c =
mu_u * intQuants.ureaConcentration() / (
k_u + intQuants.ureaConcentration());
309 if (intQuants.oxygenConcentration() < 0) {
310 k_g =
mu * intQuants.oxygenConcentration() /
k_n;
312 if (intQuants.ureaConcentration() < 0) {
313 k_c =
mu_u * intQuants.ureaConcentration() /
k_u;
318 source[Indices::contiMicrobialEqIdx] += intQuants.microbialConcentration() * intQuants.porosity() *
320 rho_b * intQuants.biofilmVolumeFraction() *
k_str *
pow(normVelocityCell / intQuants.porosity(),
eta);
322 source[Indices::contiOxygenEqIdx] -= (intQuants.microbialConcentration() * intQuants.porosity() *
323 b +
rho_b * intQuants.biofilmVolumeFraction()) * F *
k_g;
325 source[Indices::contiUreaEqIdx] -=
rho_b * intQuants.biofilmVolumeFraction() *
k_c;
327 source[Indices::contiBiofilmEqIdx] += intQuants.biofilmVolumeFraction() * (Y *
k_g -
k_d -
329 intQuants.biofilmVolumeFraction() *
k_c / (intQuants.porosity() +
330 intQuants.biofilmVolumeFraction())) +
k_a * intQuants.microbialConcentration() *
331 intQuants.porosity() *
b /
rho_b;
333 source[Indices::contiCalciteEqIdx] += (
rho_b /
rho_c) * intQuants.biofilmVolumeFraction() *
Y_uc *
k_c;
341 [](
const auto acc,
const auto& info)
342 { return max(acc, std::abs(info.velocity[1])); });
345 const auto& fs = intQuants.fluidState();
346 const auto& Sw = fs.saturation(waterPhaseIdx);
347 const auto& Rsw = fs.Rsw();
348 const auto&
rhow = fs.density(waterPhaseIdx);
349 unsigned pvtRegionIndex = fs.pvtRegionIndex();
351 const auto&
xG = RswToMassFraction(pvtRegionIndex, Rsw);
354 const Evaluation& poro = intQuants.porosity();
355 Scalar
rho_gRef = FluidSystem::referenceDensity(FluidSystem::gasPhaseIdx, pvtRegionIndex);
365 source[contiMicrobialEqIdx] += Sw * intQuants.microbialConcentration() * intQuants.porosity() *
b
367 + intQuants.biofilmVolumeFraction() *
rho_b *
k_str
368 *
pow(normVelocityCell / intQuants.porosity(),
eta);
370 source[contiBiofilmEqIdx] += (
k_g -
k_d -
k_str *
pow(normVelocityCell / intQuants.porosity(),
eta))
371 * intQuants.biofilmVolumeFraction()
372 +
k_a * Sw * intQuants.microbialConcentration() * intQuants.porosity() *
b /
rho_b;
375 unsigned activeGasCompIdx = FluidSystem::canonicalToActiveCompIdx(gasCompIdx);
381 static void addSource([[
maybe_unused]] RateVector& source,
386 if constexpr (enableMICP) {
387 const auto& problem = elemCtx.problem();
388 const auto& intQuants = elemCtx.intensiveQuantities(dofIdx,
timeIdx);
389 addSource(source, problem, intQuants, dofIdx);
453 static const Scalar yieldUreaToCalciteCoefficient(
unsigned satnumRegionIdx)
458 static const Scalar bioDiffCoefficient(
unsigned pvtRegionIdx,
unsigned compIdx)
460 return params_.bioDiffCoefficient_[pvtRegionIdx][
compIdx];
463 static const TabulatedFunction& permfactTable(
const ElementContext& elemCtx,
471 static const TabulatedFunction& permfactTable(
unsigned satnumRegionIdx)
481 static bool hasPcfactTables()
483 if constexpr (enableBioeffects && !enableMICP) {
484 return !params_.pcfactTable_.empty();
494 static Evaluation RswToMassFraction(
unsigned regionIdx,
const Evaluation& Rsw) {
495 Scalar
rho_wRef = FluidSystem::referenceDensity(FluidSystem::waterPhaseIdx,
regionIdx);
496 Scalar
rho_gRef = FluidSystem::referenceDensity(FluidSystem::gasPhaseIdx,
regionIdx);