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> 56 template <
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>
147 OPM_HOST_DEVICE
static void addDiffusiveFlux(RateVectorT& flux,
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>
237 OPM_HOST_DEVICE
static void addBioDiffFlux(RateVector& flux,
238 const IntensiveQuantities& inIq,
239 const IntensiveQuantities& exIq,
240 const Evaluation& diffusivity,
241 const EvaluationArray& effectiveBioDiffCoefficient)
243 if constexpr (enableBioeffects) {
244 using BioeffectsParams = BlackOilBioeffectsParams<Scalar>;
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 304 template <
typename TypeTag>
306 BlackOilDiffusionModule<TypeTag, true>::use_mole_fraction_;
316 template <
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>
453 void update_(FluidState& fluidState,
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_{};
513 template <
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 };
530 using EvaluationArray = std::array<std::array<Evaluation, numComponents>, numPhases>;
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);
561 OPM_HOST_DEVICE
static void update(EvaluationArray& effectiveDiffusionCoefficient,
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>
601 void updateBoundary_(
const Context&,
606 throw std::runtime_error(
"Not implemented: Diffusion across boundary not implemented for blackoil");
617 {
return diffusivity_; }
627 {
return effectiveDiffusionCoefficient_[phaseIdx][compIdx]; }
629 OPM_HOST_DEVICE
const auto& effectiveDiffusionCoefficient()
const 630 {
return effectiveDiffusionCoefficient_; }
632 OPM_HOST_DEVICE
const Evaluation& effectiveBioDiffCoefficient(
unsigned compIdx)
const 633 {
return effectiveBioDiffCoefficient_[compIdx]; }
635 OPM_HOST_DEVICE
const auto& effectiveBioDiffCoefficient()
const{
636 return effectiveBioDiffCoefficient_;
641 EvaluationArray effectiveDiffusionCoefficient_;
642 std::array<Evaluation, numBioInWat> effectiveBioDiffCoefficient_;
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< std::array< Evaluation, numComponents >, numPhases > & diffusionCoefficients() const
Returns all the diffusion coefficients.
Definition: blackoildiffusionmodule.hh:378
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
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
Provides the volumetric quantities required for the calculation of molecular diffusive fluxes...
Defines the common properties required by the porous medium multi-phase models.
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
Structs needed for tpfalinearizer and its gpuparams struct extracted to be defined in one place that ...
Definition: blackoilbioeffectsmodules.hh:45
OPM_HOST_DEVICE Scalar diffusivity() const
The diffusivity of the face.
Definition: blackoildiffusionmodule.hh:616
Contains classes extending the black-oil model.
OPM_HOST_DEVICE const std::array< Evaluation, numPhases > & tortuosities() const
Returns all the tortuosities.
Definition: blackoildiffusionmodule.hh:391
Declares the properties required by the black oil model.
Declare the properties used by the infrastructure code of the finite volume discretizations.
static void registerParameters()
Register all run-time parameters for the diffusion module.
Definition: blackoildiffusionmodule.hh:100
Provides the quantities required to calculate diffusive mass fluxes.
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
OPM_HOST_DEVICE Evaluation bioDiffCoefficient(unsigned compIdx) const
Returns the molecular diffusion coefficient for a biocomponent in the water phase.
Definition: blackoildiffusionmodule.hh:414
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
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 initFromState(const EclipseState &eclState)
Initialize all internal data structures needed by the diffusion module.
Definition: blackoildiffusionmodule.hh:87
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
Provides the auxiliary methods required for consideration of the diffusion equation.
void update_(const ElementContext &elemCtx, unsigned faceIdx, unsigned timeIdx)
Update the quantities required to calculate the diffusive mass fluxes.
Definition: blackoildiffusionmodule.hh:537
Definition: blackoildiffusionmodule.hh:514