28#ifndef OPM_BLACKOIL_DIFFUSION_MODULE_HH
29#define OPM_BLACKOIL_DIFFUSION_MODULE_HH
31#include <dune/common/fvector.hh>
33#include <opm/common/utility/gpuDecorators.hpp>
35#include <opm/input/eclipse/EclipseState/EclipseState.hpp>
37#include <opm/material/common/MathToolbox.hpp>
38#include <opm/material/common/Valgrind.hpp>
56template <
class TypeTag>
66 static constexpr bool enableBioeffects = getPropValue<TypeTag, Properties::EnableBioeffects>();
67 using BioeffectsModule = BlackOilBioeffectsModule<TypeTag, enableBioeffects>;
69 enum { numPhases = FluidSystem::numPhases };
70 enum { conti0EqIdx = Indices::conti0EqIdx };
72 enum { enableMICP = Indices::enableMICP };
74 static constexpr unsigned contiMicrobialEqIdx = Indices::contiMicrobialEqIdx;
75 static constexpr unsigned contiOxygenEqIdx = Indices::contiOxygenEqIdx;
76 static constexpr unsigned waterPhaseIdx = FluidSystem::waterPhaseIdx;
77 static constexpr unsigned contiUreaEqIdx = Indices::contiUreaEqIdx;
79 using Toolbox = MathToolbox<Evaluation>;
90 #if OPM_IS_INSIDE_HOST_FUNCTION
91 use_mole_fraction_ = eclState.getTableManager().diffMoleFraction();
93 OPM_THROW(std::runtime_error,
"Diffusion module: Calling initFromState not expected on GPU.");
125 template <
class Context>
127 unsigned spaceIdx,
unsigned timeIdx)
130 if (!FluidSystem::enableDiffusion()) {
134 const auto& extQuants = context.extensiveQuantities(spaceIdx, timeIdx);
135 const auto& inIq = context.intensiveQuantities(extQuants.interiorIndex(), timeIdx);
136 const auto& exIq = context.intensiveQuantities(extQuants.exteriorIndex(), timeIdx);
137 const auto& diffusivity = extQuants.diffusivity();
138 const auto& effectiveDiffusionCoefficient = extQuants.effectiveDiffusionCoefficient();
139 addDiffusiveFlux(flux, inIq, exIq, diffusivity, effectiveDiffusionCoefficient);
140 if constexpr (enableBioeffects) {
141 const auto& effectiveBioDiffCoefficient = extQuants.effectiveBioDiffCoefficient();
142 addBioDiffFlux(flux, inIq, exIq, diffusivity, effectiveBioDiffCoefficient);
146 template<
class IntensiveQuantities,
class EvaluationArray,
class RateVectorT>
148 const IntensiveQuantities& inIq,
149 const IntensiveQuantities& exIq,
150 const Evaluation& diffusivity,
151 const EvaluationArray& effectiveDiffusionCoefficient)
153 const FluidSystem& fsys = inIq.getFluidSystem();
155 const auto& inFs = inIq.fluidState();
156 const auto& exFs = exIq.fluidState();
157 unsigned pvtRegionIndex = inFs.pvtRegionIndex();
158 Evaluation diffR = 0.0;
160 for (
unsigned phaseIdx = 0; phaseIdx < numPhases; ++phaseIdx) {
161 if (!fsys.phaseIsActive(phaseIdx)) {
166 if (!fsys.enableDissolvedGasInWater() && fsys.waterPhaseIdx == phaseIdx) {
171 if (fsys.gasPhaseIdx == phaseIdx && !fsys.phaseIsActive(fsys.oilPhaseIdx)) {
176 Evaluation bSAvg = inFs.saturation(phaseIdx) * inFs.invB(phaseIdx);
177 bSAvg += Toolbox::value(exFs.saturation(phaseIdx)) * Toolbox::value(exFs.invB(phaseIdx));
181 if (bSAvg < 1.0e-6) {
184 Evaluation convFactor = 1.0;
185 if (fsys.enableDissolvedGas() &&
186 fsys.phaseIsActive(fsys.gasPhaseIdx) &&
187 phaseIdx == fsys.oilPhaseIdx)
189 const Evaluation rsAvg = (inFs.Rs() + Toolbox::value(exFs.Rs())) / 2;
190 convFactor = 1.0 / (toFractionGasOil(pvtRegionIndex, fsys) + rsAvg);
191 diffR = inFs.Rs() - Toolbox::value(exFs.Rs());
193 if (fsys.enableVaporizedOil() &&
194 fsys.phaseIsActive(fsys.oilPhaseIdx) &&
195 phaseIdx == fsys.gasPhaseIdx)
197 const Evaluation rvAvg = (inFs.Rv() + Toolbox::value(exFs.Rv())) / 2;
198 convFactor = toFractionGasOil(pvtRegionIndex, fsys) /
199 (1.0 + rvAvg * toFractionGasOil(pvtRegionIndex, fsys));
200 diffR = inFs.Rv() - Toolbox::value(exFs.Rv());
202 if (fsys.enableDissolvedGasInWater() && phaseIdx == fsys.waterPhaseIdx) {
203 const Evaluation rsAvg = (inFs.Rsw() + Toolbox::value(exFs.Rsw())) / 2;
204 convFactor = 1.0 / (toFractionGasWater(pvtRegionIndex, fsys) + rsAvg);
205 diffR = inFs.Rsw() - Toolbox::value(exFs.Rsw());
207 if (fsys.enableVaporizedWater() && phaseIdx == fsys.gasPhaseIdx) {
208 const Evaluation rvAvg = (inFs.Rvw() + Toolbox::value(exFs.Rvw())) / 2;
209 convFactor = toFractionGasWater(pvtRegionIndex, fsys) /
210 (1.0 + rvAvg * toFractionGasWater(pvtRegionIndex, fsys));
211 diffR = inFs.Rvw() - Toolbox::value(exFs.Rvw());
215 const unsigned solventCompIdx = fsys.solventComponentIndex(phaseIdx);
216 const unsigned activeSolventCompIdx = fsys.canonicalToActiveCompIdx(solventCompIdx);
217 flux[conti0EqIdx + activeSolventCompIdx] +=
222 effectiveDiffusionCoefficient[phaseIdx][solventCompIdx];
225 const unsigned soluteCompIdx = fsys.soluteComponentIndex(phaseIdx);
226 const unsigned activeSoluteCompIdx = fsys.canonicalToActiveCompIdx(soluteCompIdx);
227 flux[conti0EqIdx + activeSoluteCompIdx] +=
232 effectiveDiffusionCoefficient[phaseIdx][soluteCompIdx];
236 template<
class IntensiveQuantities,
class EvaluationArray>
238 const IntensiveQuantities& inIq,
239 const IntensiveQuantities& exIq,
240 const Evaluation& diffusivity,
241 const EvaluationArray& effectiveBioDiffCoefficient)
243 if constexpr (enableBioeffects) {
245 const auto& inFs = inIq.fluidState();
246 const auto& exFs = exIq.fluidState();
247 Evaluation diffR = 0.0;
250 Evaluation bAvg = (inFs.saturation(waterPhaseIdx) * inFs.invB(waterPhaseIdx) +
251 Toolbox::value(exFs.saturation(waterPhaseIdx)) * Toolbox::value(exFs.invB(waterPhaseIdx))) / 2;
252 diffR = inIq.microbialConcentration() - Toolbox::value(exIq.microbialConcentration());
253 flux[contiMicrobialEqIdx] +=
257 effectiveBioDiffCoefficient[BioeffectsParams::micrDiffIdx];
258 if constexpr(enableMICP) {
259 diffR = inIq.oxygenConcentration() - Toolbox::value(exIq.oxygenConcentration());
260 flux[contiOxygenEqIdx] +=
264 effectiveBioDiffCoefficient[BioeffectsParams::oxygDiffIdx];
265 diffR = inIq.ureaConcentration() - Toolbox::value(exIq.ureaConcentration());
266 flux[contiUreaEqIdx] +=
270 effectiveBioDiffCoefficient[BioeffectsParams::ureaDiffIdx];
276 template<
class Flu
idSystemT>
277 OPM_HOST_DEVICE
static Scalar toFractionGasOil (
unsigned regionIdx,
const FluidSystemT& fsys)
279 const Scalar mMOil = use_mole_fraction_ ? fsys.molarMass(fsys.oilCompIdx, regionIdx) : 1;
280 const Scalar rhoO = fsys.referenceDensity(fsys.oilPhaseIdx, regionIdx);
281 const Scalar mMGas = use_mole_fraction_ ? fsys.molarMass(fsys.gasCompIdx, regionIdx) : 1;
282 const Scalar rhoG = fsys.referenceDensity(fsys.gasPhaseIdx, regionIdx);
283 return rhoO * mMGas / (rhoG * mMOil);
286 template<
class Flu
idSystemT>
287 OPM_HOST_DEVICE
static Scalar toFractionGasWater (
unsigned regionIdx,
const FluidSystemT& fsys)
289 const Scalar mMWater = use_mole_fraction_ ? fsys.molarMass(fsys.waterCompIdx, regionIdx) : 1;
290 const Scalar rhoW = fsys.referenceDensity(fsys.waterPhaseIdx, regionIdx);
291 const Scalar mMGas = use_mole_fraction_ ? fsys.molarMass(fsys.gasCompIdx, regionIdx) : 1;
292 const Scalar rhoG = fsys.referenceDensity(fsys.gasPhaseIdx, regionIdx);
293 return rhoW * mMGas / (rhoG * mMWater);
296 #if OPM_IS_INSIDE_DEVICE_FUNCTION
297 constexpr static bool use_mole_fraction_ =
false;
299 static bool use_mole_fraction_;
303#if OPM_IS_INSIDE_HOST_FUNCTION
304template <
typename TypeTag>
316template <
class TypeTag>
325 static constexpr bool enableBioeffects = getPropValue<TypeTag, Properties::EnableBioeffects>();
326 using BioeffectsModule = BlackOilBioeffectsModule<TypeTag, enableBioeffects>;
328 enum { numPhases = FluidSystem::numPhases };
329 enum { numComponents = FluidSystem::numComponents };
330 enum { enableMICP = Indices::enableMICP };
331 enum { numBioInWat = Indices::numBioInWat };
333 static constexpr unsigned waterPhaseIdx = FluidSystem::waterPhaseIdx;
343 const std::array<std::array<Evaluation, numComponents>, numPhases>& diffusionCoefficient)
344 : tortuosity_(tortuosity)
345 , diffusionCoefficient_(diffusionCoefficient)
355 if (FluidSystem::enableDiffusion()) {
356 tortuosity_ = rhs.tortuosity_;
357 diffusionCoefficient_ = rhs.diffusionCoefficient_;
367 {
return diffusionCoefficient_[phaseIdx][compIdx]; }
373 OPM_HOST_DEVICE Evaluation
tortuosity(
unsigned phaseIdx)
const
374 {
return tortuosity_[phaseIdx]; }
384 static constexpr bool enableTortuosity =
false;
385 if constexpr (enableTortuosity) {
386 return tortuosity_[phaseIdx] * diffusionCoefficient_[phaseIdx][compIdx];
388 return diffusionCoefficient_[phaseIdx][compIdx];
397 {
return bioDiffCoefficient_[compIdx]; }
406 static bool enableTortuosity =
false;
407 if (enableTortuosity)
408 return tortuosity_[waterPhaseIdx] * bioDiffCoefficient_[compIdx];
410 return bioDiffCoefficient_[compIdx];
418 template <
class Flu
idState>
420 const unsigned regionIdx,
421 const ElementContext& elemCtx,
426 if (!FluidSystem::enableDiffusion()) {
430 const auto& intQuants = elemCtx.intensiveQuantities(dofIdx, timeIdx);
431 update_(fluidState, regionIdx, intQuants);
434 template<
class Flu
idState>
436 const unsigned regionIdx,
437 const IntensiveQuantities& intQuants)
439 using Toolbox = MathToolbox<Evaluation>;
441 for (
unsigned phaseIdx = 0; phaseIdx < numPhases; ++phaseIdx) {
442 if (!FluidSystem::phaseIsActive(phaseIdx)) {
447 if (!FluidSystem::enableDissolvedGasInWater() && FluidSystem::waterPhaseIdx == phaseIdx) {
454 constexpr double myeps = 0.0001;
455 const Evaluation& base =
457 intQuants.porosity() *
458 intQuants.fluidState().saturation(phaseIdx));
459 tortuosity_[phaseIdx] =
460 1.0 / (intQuants.porosity() * intQuants.porosity()) *
461 Toolbox::pow(base, 10.0 / 3.0);
463 using PCache =
typename FluidSystem::template ParameterCache<Scalar>;
464 PCache pcache(regionIdx);
465 for (
unsigned compIdx = 0; compIdx < numComponents; ++compIdx) {
466 diffusionCoefficient_[phaseIdx][compIdx] =
467 FluidSystem::diffusionCoefficient(fluidState,
474 if constexpr (enableBioeffects) {
475 unsigned pvtRegionIndex = intQuants.pvtRegionIndex();
476 for (
unsigned compIdx = 0; compIdx < numBioInWat; ++compIdx) {
477 bioDiffCoefficient_[compIdx] =
478 BioeffectsModule::bioDiffCoefficient(pvtRegionIndex, compIdx);
484 std::array<Evaluation, numPhases> tortuosity_{};
485 std::array<std::array<Evaluation, numComponents>, numPhases> diffusionCoefficient_{};
486 std::array<Evaluation, numBioInWat> bioDiffCoefficient_{};
495template <
class TypeTag>
505 enum { numPhases = getPropValue<TypeTag, Properties::NumPhases>() };
506 enum { numComponents = getPropValue<TypeTag, Properties::NumComponents>() };
507 static constexpr bool enableBioeffects = getPropValue<TypeTag, Properties::EnableBioeffects>();
508 enum { enableMICP = Indices::enableMICP };
509 enum { numBioInWat = Indices::numBioInWat };
519 void update_(
const ElementContext& elemCtx,
unsigned faceIdx,
unsigned timeIdx)
522 if (!FluidSystem::enableDiffusion()) {
526 const auto& stencil = elemCtx.stencil(timeIdx);
527 const auto& face = stencil.interiorFace(faceIdx);
528 const auto& extQuants = elemCtx.extensiveQuantities(faceIdx, timeIdx);
529 const auto& intQuantsInside = elemCtx.intensiveQuantities(extQuants.interiorIndex(), timeIdx);
530 const auto& intQuantsOutside = elemCtx.intensiveQuantities(extQuants.exteriorIndex(), timeIdx);
532 const Scalar diff = elemCtx.problem().diffusivity(elemCtx, face.interiorIndex(), face.exteriorIndex());
533 const Scalar faceArea = face.area();
534 diffusivity_ = diff / faceArea;
535 update(effectiveDiffusionCoefficient_, intQuantsInside, intQuantsOutside);
536 Valgrind::CheckDefined(diffusivity_);
537 if constexpr (enableBioeffects) {
538 updateBio(effectiveBioDiffCoefficient_, intQuantsInside, intQuantsOutside);
544 const IntensiveQuantities& intQuantsInside,
545 const IntensiveQuantities& intQuantsOutside)
547 const FluidSystem& fsys = intQuantsInside.getFluidSystem();
552 for (
unsigned phaseIdx = 0; phaseIdx < numPhases; ++phaseIdx) {
553 if (!fsys.phaseIsActive(phaseIdx)) {
557 if (!fsys.enableDissolvedGasInWater() && fsys.waterPhaseIdx == phaseIdx) {
560 for (
unsigned compIdx = 0; compIdx < numComponents; ++compIdx) {
561 effectiveDiffusionCoefficient[phaseIdx][compIdx] =
562 0.5 * (intQuantsInside.effectiveDiffusionCoefficient(phaseIdx, compIdx) +
563 intQuantsOutside.effectiveDiffusionCoefficient(phaseIdx, compIdx));
564 Valgrind::CheckDefined(effectiveDiffusionCoefficient[phaseIdx][compIdx]);
569 static void updateBio(std::array<Evaluation, numBioInWat>& effectiveBioDiffCoefficient,
570 const IntensiveQuantities& intQuantsInside,
571 const IntensiveQuantities& intQuantsOutside) {
573 for (
unsigned compIdx = 0; compIdx < numBioInWat; ++compIdx) {
574 effectiveBioDiffCoefficient[compIdx] =
575 0.5 * (intQuantsInside.effectiveBioDiffCoefficient(compIdx) +
576 intQuantsOutside.effectiveBioDiffCoefficient(compIdx));
577 Valgrind::CheckDefined(effectiveBioDiffCoefficient[compIdx]);
582 template <
class Context,
class Flu
idState>
588 throw std::runtime_error(
"Not implemented: Diffusion across boundary not implemented for blackoil");
599 {
return diffusivity_; }
609 {
return effectiveDiffusionCoefficient_[phaseIdx][compIdx]; }
612 {
return effectiveDiffusionCoefficient_; }
615 {
return effectiveBioDiffCoefficient_[compIdx]; }
618 return effectiveBioDiffCoefficient_;
623 EvaluationArray effectiveDiffusionCoefficient_;
624 std::array<Evaluation, numBioInWat> effectiveBioDiffCoefficient_;
Contains classes extending the black-oil model. \detail This file holds dummy definitions,...
Declares the properties required by the black oil model.
Definition: blackoildiffusionmodule.hh:497
static void update(EvaluationArray &effectiveDiffusionCoefficient, const IntensiveQuantities &intQuantsInside, const IntensiveQuantities &intQuantsOutside)
Definition: blackoildiffusionmodule.hh:543
OPM_HOST_DEVICE const Evaluation & effectiveBioDiffCoefficient(unsigned compIdx) const
Definition: blackoildiffusionmodule.hh:614
OPM_HOST_DEVICE const Evaluation & effectiveDiffusionCoefficient(unsigned phaseIdx, unsigned compIdx) const
The effective diffusion coefficient of a component in a fluid phase at the face's integration point.
Definition: blackoildiffusionmodule.hh:608
static void updateBio(std::array< Evaluation, numBioInWat > &effectiveBioDiffCoefficient, const IntensiveQuantities &intQuantsInside, const IntensiveQuantities &intQuantsOutside)
Definition: blackoildiffusionmodule.hh:569
std::array< std::array< Evaluation, numComponents >, numPhases > EvaluationArray
Definition: blackoildiffusionmodule.hh:512
OPM_HOST_DEVICE Scalar diffusivity() const
The diffusivity of the face.
Definition: blackoildiffusionmodule.hh:598
OPM_HOST_DEVICE const auto & effectiveDiffusionCoefficient() const
Definition: blackoildiffusionmodule.hh:611
void updateBoundary_(const Context &, unsigned, unsigned, const FluidState &)
Definition: blackoildiffusionmodule.hh:583
OPM_HOST_DEVICE const auto & effectiveBioDiffCoefficient() const
Definition: blackoildiffusionmodule.hh:617
void update_(const ElementContext &elemCtx, unsigned faceIdx, unsigned timeIdx)
Update the quantities required to calculate the diffusive mass fluxes.
Definition: blackoildiffusionmodule.hh:519
Provides the quantities required to calculate diffusive mass fluxes.
BlackOilDiffusionIntensiveQuantities & operator=(const BlackOilDiffusionIntensiveQuantities &rhs)
Definition: blackoildiffusionmodule.hh:349
OPM_HOST_DEVICE Evaluation diffusionCoefficient(unsigned phaseIdx, unsigned compIdx) const
Returns the molecular diffusion coefficient for a component in a phase.
Definition: blackoildiffusionmodule.hh:366
OPM_HOST_DEVICE Evaluation effectiveDiffusionCoefficient(unsigned phaseIdx, unsigned compIdx) const
Returns the effective molecular diffusion coefficient of the porous medium for a component in a phase...
Definition: blackoildiffusionmodule.hh:380
BlackOilDiffusionIntensiveQuantities(BlackOilDiffusionIntensiveQuantities &&) noexcept=default
OPM_HOST_DEVICE Evaluation tortuosity(unsigned phaseIdx) const
Returns the tortuousity of the sub-domain of a fluid phase in the porous medium.
Definition: blackoildiffusionmodule.hh:373
BlackOilDiffusionIntensiveQuantities()=default
OPM_HOST_DEVICE Evaluation bioDiffCoefficient(unsigned compIdx) const
Returns the molecular diffusion coefficient for a biocomponent in the water phase.
Definition: blackoildiffusionmodule.hh:396
void update_(FluidState &fluidState, const unsigned regionIdx, const ElementContext &elemCtx, unsigned dofIdx, unsigned timeIdx)
Update the quantities required to calculate diffusive mass fluxes.
Definition: blackoildiffusionmodule.hh:419
OPM_HOST_DEVICE Evaluation effectiveBioDiffCoefficient(unsigned compIdx) const
Returns the effective molecular diffusion coefficient of the porous medium for a biocomponent in the ...
Definition: blackoildiffusionmodule.hh:403
void update_(FluidState &fluidState, const unsigned regionIdx, const IntensiveQuantities &intQuants)
Definition: blackoildiffusionmodule.hh:435
Provides the volumetric quantities required for the calculation of molecular diffusive fluxes.
static OPM_HOST_DEVICE void addBioDiffFlux(RateVector &flux, const IntensiveQuantities &inIq, const IntensiveQuantities &exIq, const Evaluation &diffusivity, const EvaluationArray &effectiveBioDiffCoefficient)
Definition: blackoildiffusionmodule.hh:237
static OPM_HOST_DEVICE void addDiffusiveFlux(RateVector &flux, const Context &context, unsigned spaceIdx, unsigned timeIdx)
Adds the mass flux due to molecular diffusion to the flux vector over the integration point....
Definition: blackoildiffusionmodule.hh:126
static void initFromState(const EclipseState &eclState)
Initialize all internal data structures needed by the diffusion module.
Definition: blackoildiffusionmodule.hh:87
static void registerParameters()
Register all run-time parameters for the diffusion module.
Definition: blackoildiffusionmodule.hh:100
static OPM_HOST_DEVICE void addDiffusiveFlux(RateVectorT &flux, const IntensiveQuantities &inIq, const IntensiveQuantities &exIq, const Evaluation &diffusivity, const EvaluationArray &effectiveDiffusionCoefficient)
Definition: blackoildiffusionmodule.hh:147
Provides the auxiliary methods required for consideration of the diffusion equation.
Declare the properties used by the infrastructure code of the finite volume discretizations.
Defines the common properties required by the porous medium multi-phase models.
Definition: blackoilbioeffectsmodules.hh:45
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
Struct holding the parameters for the BlackOilBioeffectsModule class.
Definition: blackoilbioeffectsparams.hpp:42