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)
348 template <
class OtherTypeTag>
350 : tortuosity_(other.tortuosity())
351 , diffusionCoefficient_(other.diffusionCoefficients())
361 if (FluidSystem::enableDiffusion()) {
362 tortuosity_ = rhs.tortuosity_;
363 diffusionCoefficient_ = rhs.diffusionCoefficient_;
373 {
return diffusionCoefficient_[phaseIdx][compIdx]; }
379 {
return diffusionCoefficient_; }
385 OPM_HOST_DEVICE Evaluation
tortuosity(
unsigned phaseIdx)
const
386 {
return tortuosity_[phaseIdx]; }
391 OPM_HOST_DEVICE
const std::array<Evaluation, numPhases>&
tortuosities()
const
392 {
return tortuosity_; }
402 static constexpr bool enableTortuosity =
false;
403 if constexpr (enableTortuosity) {
404 return tortuosity_[phaseIdx] * diffusionCoefficient_[phaseIdx][compIdx];
406 return diffusionCoefficient_[phaseIdx][compIdx];
415 {
return bioDiffCoefficient_[compIdx]; }
424 static bool enableTortuosity =
false;
425 if (enableTortuosity)
426 return tortuosity_[waterPhaseIdx] * bioDiffCoefficient_[compIdx];
428 return bioDiffCoefficient_[compIdx];
436 template <
class Flu
idState>
438 const unsigned regionIdx,
439 const ElementContext& elemCtx,
444 if (!FluidSystem::enableDiffusion()) {
448 const auto& intQuants = elemCtx.intensiveQuantities(dofIdx, timeIdx);
449 update_(fluidState, regionIdx, intQuants);
452 template<
class Flu
idState>
454 const unsigned regionIdx,
455 const IntensiveQuantities& intQuants)
457 using Toolbox = MathToolbox<Evaluation>;
459 for (
unsigned phaseIdx = 0; phaseIdx < numPhases; ++phaseIdx) {
460 if (!FluidSystem::phaseIsActive(phaseIdx)) {
465 if (!FluidSystem::enableDissolvedGasInWater() && FluidSystem::waterPhaseIdx == phaseIdx) {
472 constexpr double myeps = 0.0001;
473 const Evaluation& base =
475 intQuants.porosity() *
476 intQuants.fluidState().saturation(phaseIdx));
477 tortuosity_[phaseIdx] =
478 1.0 / (intQuants.porosity() * intQuants.porosity()) *
479 Toolbox::pow(base, 10.0 / 3.0);
481 using PCache =
typename FluidSystem::template ParameterCache<Scalar>;
482 PCache pcache(regionIdx);
483 for (
unsigned compIdx = 0; compIdx < numComponents; ++compIdx) {
484 diffusionCoefficient_[phaseIdx][compIdx] =
485 FluidSystem::diffusionCoefficient(fluidState,
492 if constexpr (enableBioeffects) {
493 unsigned pvtRegionIndex = intQuants.pvtRegionIndex();
494 for (
unsigned compIdx = 0; compIdx < numBioInWat; ++compIdx) {
495 bioDiffCoefficient_[compIdx] =
496 BioeffectsModule::bioDiffCoefficient(pvtRegionIndex, compIdx);
502 std::array<Evaluation, numPhases> tortuosity_{};
503 std::array<std::array<Evaluation, numComponents>, numPhases> diffusionCoefficient_{};
504 std::array<Evaluation, numBioInWat> bioDiffCoefficient_{};
513template <
class TypeTag>
523 enum { numPhases = getPropValue<TypeTag, Properties::NumPhases>() };
524 enum { numComponents = getPropValue<TypeTag, Properties::NumComponents>() };
525 static constexpr bool enableBioeffects = getPropValue<TypeTag, Properties::EnableBioeffects>();
526 enum { enableMICP = Indices::enableMICP };
527 enum { numBioInWat = Indices::numBioInWat };
537 void update_(
const ElementContext& elemCtx,
unsigned faceIdx,
unsigned timeIdx)
540 if (!FluidSystem::enableDiffusion()) {
544 const auto& stencil = elemCtx.stencil(timeIdx);
545 const auto& face = stencil.interiorFace(faceIdx);
546 const auto& extQuants = elemCtx.extensiveQuantities(faceIdx, timeIdx);
547 const auto& intQuantsInside = elemCtx.intensiveQuantities(extQuants.interiorIndex(), timeIdx);
548 const auto& intQuantsOutside = elemCtx.intensiveQuantities(extQuants.exteriorIndex(), timeIdx);
550 const Scalar diff = elemCtx.problem().diffusivity(elemCtx, face.interiorIndex(), face.exteriorIndex());
551 const Scalar faceArea = face.area();
552 diffusivity_ = diff / faceArea;
553 update(effectiveDiffusionCoefficient_, intQuantsInside, intQuantsOutside);
554 Valgrind::CheckDefined(diffusivity_);
555 if constexpr (enableBioeffects) {
556 updateBio(effectiveBioDiffCoefficient_, intQuantsInside, intQuantsOutside);
562 const IntensiveQuantities& intQuantsInside,
563 const IntensiveQuantities& intQuantsOutside)
565 const FluidSystem& fsys = intQuantsInside.getFluidSystem();
570 for (
unsigned phaseIdx = 0; phaseIdx < numPhases; ++phaseIdx) {
571 if (!fsys.phaseIsActive(phaseIdx)) {
575 if (!fsys.enableDissolvedGasInWater() && fsys.waterPhaseIdx == phaseIdx) {
578 for (
unsigned compIdx = 0; compIdx < numComponents; ++compIdx) {
579 effectiveDiffusionCoefficient[phaseIdx][compIdx] =
580 0.5 * (intQuantsInside.effectiveDiffusionCoefficient(phaseIdx, compIdx) +
581 intQuantsOutside.effectiveDiffusionCoefficient(phaseIdx, compIdx));
582 Valgrind::CheckDefined(effectiveDiffusionCoefficient[phaseIdx][compIdx]);
587 static void updateBio(std::array<Evaluation, numBioInWat>& effectiveBioDiffCoefficient,
588 const IntensiveQuantities& intQuantsInside,
589 const IntensiveQuantities& intQuantsOutside) {
591 for (
unsigned compIdx = 0; compIdx < numBioInWat; ++compIdx) {
592 effectiveBioDiffCoefficient[compIdx] =
593 0.5 * (intQuantsInside.effectiveBioDiffCoefficient(compIdx) +
594 intQuantsOutside.effectiveBioDiffCoefficient(compIdx));
595 Valgrind::CheckDefined(effectiveBioDiffCoefficient[compIdx]);
600 template <
class Context,
class Flu
idState>
606 throw std::runtime_error(
"Not implemented: Diffusion across boundary not implemented for blackoil");
617 {
return diffusivity_; }
627 {
return effectiveDiffusionCoefficient_[phaseIdx][compIdx]; }
630 {
return effectiveDiffusionCoefficient_; }
633 {
return effectiveBioDiffCoefficient_[compIdx]; }
636 return effectiveBioDiffCoefficient_;
641 EvaluationArray effectiveDiffusionCoefficient_;
642 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:515
static OPM_HOST_DEVICE void update(EvaluationArray &effectiveDiffusionCoefficient, const IntensiveQuantities &intQuantsInside, const IntensiveQuantities &intQuantsOutside)
Definition: blackoildiffusionmodule.hh:561
OPM_HOST_DEVICE const Evaluation & effectiveBioDiffCoefficient(unsigned compIdx) const
Definition: blackoildiffusionmodule.hh:632
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:626
static void updateBio(std::array< Evaluation, numBioInWat > &effectiveBioDiffCoefficient, const IntensiveQuantities &intQuantsInside, const IntensiveQuantities &intQuantsOutside)
Definition: blackoildiffusionmodule.hh:587
std::array< std::array< Evaluation, numComponents >, numPhases > EvaluationArray
Definition: blackoildiffusionmodule.hh:530
OPM_HOST_DEVICE Scalar diffusivity() const
The diffusivity of the face.
Definition: blackoildiffusionmodule.hh:616
OPM_HOST_DEVICE const auto & effectiveDiffusionCoefficient() const
Definition: blackoildiffusionmodule.hh:629
void updateBoundary_(const Context &, unsigned, unsigned, const FluidState &)
Definition: blackoildiffusionmodule.hh:601
OPM_HOST_DEVICE const auto & effectiveBioDiffCoefficient() const
Definition: blackoildiffusionmodule.hh:635
void update_(const ElementContext &elemCtx, unsigned faceIdx, unsigned timeIdx)
Update the quantities required to calculate the diffusive mass fluxes.
Definition: blackoildiffusionmodule.hh:537
Provides the quantities required to calculate diffusive mass fluxes.
BlackOilDiffusionIntensiveQuantities & operator=(const BlackOilDiffusionIntensiveQuantities &rhs)
Definition: blackoildiffusionmodule.hh:355
OPM_HOST_DEVICE Evaluation diffusionCoefficient(unsigned phaseIdx, unsigned compIdx) const
Returns the molecular diffusion coefficient for a component in a phase.
Definition: blackoildiffusionmodule.hh:372
OPM_HOST_DEVICE const std::array< Evaluation, numPhases > & tortuosities() const
Returns all the tortuosities.
Definition: blackoildiffusionmodule.hh:391
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:398
BlackOilDiffusionIntensiveQuantities(const BlackOilDiffusionIntensiveQuantities< OtherTypeTag, true > &other)
Definition: blackoildiffusionmodule.hh:349
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:385
OPM_HOST_DEVICE const std::array< std::array< Evaluation, numComponents >, numPhases > & diffusionCoefficients() const
Returns all the diffusion coefficients.
Definition: blackoildiffusionmodule.hh:378
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:414
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:437
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:421
void update_(FluidState &fluidState, const unsigned regionIdx, const IntensiveQuantities &intQuants)
Definition: blackoildiffusionmodule.hh:453
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