28#ifndef EWOMS_BLACK_OIL_FOAM_MODULE_HH
29#define EWOMS_BLACK_OIL_FOAM_MODULE_HH
31#include <dune/common/fvector.hh>
33#include <opm/common/OpmLog/OpmLog.hpp>
34#include <opm/common/utility/gpuDecorators.hpp>
36#include <opm/input/eclipse/EclipseState/Phase.hpp>
57template <class TypeTag, bool enableFoamV = getPropValue<TypeTag, Properties::EnableFoam>()>
72 using Toolbox = MathToolbox<Evaluation>;
76 static constexpr unsigned foamConcentrationIdx = Indices::foamConcentrationIdx;
77 static constexpr unsigned contiFoamEqIdx = Indices::contiFoamEqIdx;
78 static constexpr unsigned gasPhaseIdx = FluidSystem::gasPhaseIdx;
79 static constexpr unsigned waterPhaseIdx = FluidSystem::waterPhaseIdx;
81 static constexpr unsigned enableFoam = enableFoamV;
83 static constexpr unsigned numEq = getPropValue<TypeTag, Properties::NumEq>();
85 enum { enableSolvent = getPropValue<TypeTag, Properties::EnableSolvent>() };
106 if constexpr (enableFoam) {
107 if (Parameters::Get<Parameters::EnableVtkOutput>()) {
108 OpmLog::warning(
"VTK output requested, currently unsupported by the foam module.");
116 if constexpr (enableFoam) {
117 return pvIdx == foamConcentrationIdx;
127 return "foam_concentration";
135 return static_cast<Scalar
>(1.0);
140 if constexpr (enableFoam) {
141 return eqIdx == contiFoamEqIdx;
148 static std::string
eqName([[maybe_unused]]
unsigned eqIdx)
155 static Scalar
eqWeight([[maybe_unused]]
unsigned eqIdx)
160 return static_cast<Scalar
>(1.0);
164 template <
class StorageType>
166 const IntensiveQuantities& intQuants)
168 using LhsEval =
typename StorageType::value_type;
170 if constexpr (enableFoam) {
171 const auto& fs = intQuants.fluidState();
173 LhsEval surfaceVolume = Toolbox::template decay<LhsEval>(intQuants.porosity());
174 if (params_.transport_phase_ == Phase::WATER) {
175 surfaceVolume *= Toolbox::template decay<LhsEval>(fs.saturation(waterPhaseIdx)) *
176 Toolbox::template decay<LhsEval>(fs.invB(waterPhaseIdx));
177 }
else if (params_.transport_phase_ == Phase::GAS) {
178 surfaceVolume *= Toolbox::template decay<LhsEval>(fs.saturation(gasPhaseIdx)) *
179 Toolbox::template decay<LhsEval>(fs.invB(gasPhaseIdx));
180 }
else if (params_.transport_phase_ == Phase::SOLVENT) {
181 if constexpr (enableSolvent) {
182 surfaceVolume *= Toolbox::template decay<LhsEval>( intQuants.solventSaturation()) *
183 Toolbox::template decay<LhsEval>(intQuants.solventInverseFormationVolumeFactor());
186 throw std::runtime_error(
"Transport phase is GAS/WATER/SOLVENT");
190 surfaceVolume = max(surfaceVolume, 1e-10);
193 const LhsEval freeFoam = surfaceVolume *
194 Toolbox::template decay<LhsEval>(intQuants.foamConcentration());
197 const LhsEval adsorbedFoam =
198 Toolbox::template decay<LhsEval>(1.0 - intQuants.porosity()) *
199 Toolbox::template decay<LhsEval>(intQuants.foamRockDensity()) *
200 Toolbox::template decay<LhsEval>(intQuants.foamAdsorbed());
202 const LhsEval accumulationFoam = freeFoam + adsorbedFoam;
203 storage[contiFoamEqIdx] += accumulationFoam;
208 [[maybe_unused]]
const ElementContext& elemCtx,
209 [[maybe_unused]]
unsigned scvfIdx,
210 [[maybe_unused]]
unsigned timeIdx)
212 if constexpr (enableFoam) {
213 const auto& extQuants = elemCtx.extensiveQuantities(scvfIdx, timeIdx);
214 const unsigned inIdx = extQuants.interiorIndex();
221 const unsigned upIdx = extQuants.upstreamIndex(waterPhaseIdx);
222 const auto& up = elemCtx.intensiveQuantities(upIdx, timeIdx);
223 if (upIdx == inIdx) {
224 flux[contiFoamEqIdx] =
225 extQuants.volumeFlux(waterPhaseIdx) *
226 up.fluidState().invB(waterPhaseIdx) *
227 up.foamConcentration();
229 flux[contiFoamEqIdx] =
230 extQuants.volumeFlux(waterPhaseIdx) *
231 decay<Scalar>(up.fluidState().invB(waterPhaseIdx)) *
232 decay<Scalar>(up.foamConcentration());
237 const unsigned upIdx = extQuants.upstreamIndex(gasPhaseIdx);
238 const auto& up = elemCtx.intensiveQuantities(upIdx, timeIdx);
239 if (upIdx == inIdx) {
240 flux[contiFoamEqIdx] =
241 extQuants.volumeFlux(gasPhaseIdx) *
242 up.fluidState().invB(gasPhaseIdx) *
243 up.foamConcentration();
245 flux[contiFoamEqIdx] =
246 extQuants.volumeFlux(gasPhaseIdx) *
247 decay<Scalar>(up.fluidState().invB(gasPhaseIdx)) *
248 decay<Scalar>(up.foamConcentration());
253 if constexpr (enableSolvent) {
254 const unsigned upIdx = extQuants.solventUpstreamIndex();
255 const auto& up = elemCtx.intensiveQuantities(upIdx, timeIdx);
256 if (upIdx == inIdx) {
257 flux[contiFoamEqIdx] =
258 extQuants.solventVolumeFlux() *
259 up.solventInverseFormationVolumeFactor() *
260 up.foamConcentration();
262 flux[contiFoamEqIdx] =
263 extQuants.solventVolumeFlux() *
264 decay<Scalar>(up.solventInverseFormationVolumeFactor()) *
265 decay<Scalar>(up.foamConcentration());
268 throw std::runtime_error(
"Foam transport phase is SOLVENT but SOLVENT is not activated.");
272 throw std::runtime_error(
"Foam transport phase must be GAS/WATER/SOLVENT.");
285 return static_cast<Scalar
>(0.0);
288 template <
class DofEntity>
290 [[maybe_unused]] std::ostream& outstream,
291 [[maybe_unused]]
const DofEntity& dof)
293 if constexpr (enableFoam) {
294 const unsigned dofIdx = model.dofMapper().index(dof);
295 const PrimaryVariables& priVars = model.solution(0)[dofIdx];
296 outstream << priVars[foamConcentrationIdx];
300 template <
class DofEntity>
302 [[maybe_unused]] std::istream& instream,
303 [[maybe_unused]]
const DofEntity& dof)
305 if constexpr (enableFoam) {
306 const unsigned dofIdx = model.dofMapper().index(dof);
307 PrimaryVariables& priVars0 = model.solution(0)[dofIdx];
308 PrimaryVariables& priVars1 = model.solution(1)[dofIdx];
310 instream >> priVars0[foamConcentrationIdx];
313 priVars1[foamConcentrationIdx] = priVars0[foamConcentrationIdx];
321 const unsigned satnumRegionIdx = elemCtx.problem().satnumRegionIndex(elemCtx, scvIdx, timeIdx);
322 return params_.foamRockDensity_[satnumRegionIdx];
329 const unsigned satnumRegionIdx = elemCtx.problem().satnumRegionIndex(elemCtx, scvIdx, timeIdx);
330 return params_.foamAllowDesorption_[satnumRegionIdx];
337 const unsigned satnumRegionIdx = elemCtx.problem().satnumRegionIndex(elemCtx, scvIdx, timeIdx);
338 return params_.adsorbedFoamTable_[satnumRegionIdx];
345 const unsigned pvtnumRegionIdx = elemCtx.problem().pvtRegionIndex(elemCtx, scvIdx, timeIdx);
346 return params_.gasMobilityMultiplierTable_[pvtnumRegionIdx];
351 const unsigned scvIdx,
352 const unsigned timeIdx)
354 const unsigned satnumRegionIdx = elemCtx.problem().satnumRegionIndex(elemCtx, scvIdx, timeIdx);
355 return params_.foamCoefficients_[satnumRegionIdx];
359 {
return params_.transport_phase_; }
365template <
class TypeTag,
bool enableFoam>
366BlackOilFoamParams<typename BlackOilFoamModule<TypeTag, enableFoam>::Scalar>
367BlackOilFoamModule<TypeTag, enableFoam>::params_;
369template <
class TypeTag,
bool enableFoam>
379template <
class TypeTag>
394 enum { enableSolvent = getPropValue<TypeTag, Properties::EnableSolvent>() };
396 static constexpr int foamConcentrationIdx = Indices::foamConcentrationIdx;
397 static constexpr unsigned waterPhaseIdx = FluidSystem::waterPhaseIdx;
398 static constexpr unsigned oilPhaseIdx = FluidSystem::oilPhaseIdx;
399 static constexpr int gasPhaseIdx = FluidSystem::gasPhaseIdx;
411 const PrimaryVariables& priVars = elemCtx.primaryVars(dofIdx, timeIdx);
412 foamConcentration_ = priVars.makeEvaluation(foamConcentrationIdx, timeIdx);
413 const auto& fs = asImp_().fluidState_;
416 Evaluation mobilityReductionFactor = 1.0;
417 if constexpr (
false) {
421 const auto& foamCoefficients = FoamModule::foamCoefficients(elemCtx, dofIdx, timeIdx);
423 const Scalar fm_mob = foamCoefficients.fm_mob;
425 const Scalar fm_surf = foamCoefficients.fm_surf;
426 const Scalar ep_surf = foamCoefficients.ep_surf;
428 const Scalar fm_oil = foamCoefficients.fm_oil;
429 const Scalar fl_oil = foamCoefficients.fl_oil;
430 const Scalar ep_oil = foamCoefficients.ep_oil;
432 const Scalar fm_dry = foamCoefficients.fm_dry;
433 const Scalar ep_dry = foamCoefficients.ep_dry;
435 const Scalar fm_cap = foamCoefficients.fm_cap;
436 const Scalar ep_cap = foamCoefficients.ep_cap;
438 const Evaluation C_surf = foamConcentration_;
439 const Evaluation Ca = 1e10;
440 const Evaluation S_o = fs.saturation(oilPhaseIdx);
441 const Evaluation S_w = fs.saturation(waterPhaseIdx);
443 const Evaluation F1 = pow(C_surf / fm_surf, ep_surf);
444 const Evaluation F2 = pow((fm_oil - S_o) / (fm_oil - fl_oil), ep_oil);
445 const Evaluation F3 = pow(fm_cap / Ca, ep_cap);
446 const Evaluation F7 = 0.5 + atan(ep_dry * (S_w - fm_dry)) / M_PI;
448 mobilityReductionFactor = 1. / (1. + fm_mob * F1 * F2 * F3 * F7);
453 const auto& gasMobilityMultiplier = FoamModule::gasMobilityMultiplierTable(elemCtx, dofIdx, timeIdx);
454 mobilityReductionFactor = gasMobilityMultiplier.eval(foamConcentration_,
true);
458 switch (FoamModule::transportPhase()) {
460 asImp_().mobility_[waterPhaseIdx] *= mobilityReductionFactor;
463 asImp_().mobility_[gasPhaseIdx] *= mobilityReductionFactor;
466 if constexpr (enableSolvent) {
467 asImp_().solventMobility_ *= mobilityReductionFactor;
469 throw std::runtime_error(
"Foam transport phase is SOLVENT but SOLVENT is not activated.");
473 throw std::runtime_error(
"Foam transport phase must be GAS/WATER/SOLVENT.");
476 foamRockDensity_ = FoamModule::foamRockDensity(elemCtx, dofIdx, timeIdx);
478 const auto& adsorbedFoamTable = FoamModule::adsorbedFoamTable(elemCtx, dofIdx, timeIdx);
479 foamAdsorbed_ = adsorbedFoamTable.eval(foamConcentration_,
true);
480 if (!FoamModule::foamAllowDesorption(elemCtx, dofIdx, timeIdx)) {
481 throw std::runtime_error(
"Foam module does not support the 'no desorption' option.");
486 {
return foamConcentration_; }
489 {
return foamRockDensity_; }
492 {
return foamAdsorbed_; }
496 {
return *
static_cast<Implementation*
>(
this); }
503template <
class TypeTag>
517 {
throw std::runtime_error(
"foamConcentration() called but foam is disabled"); }
520 {
throw std::runtime_error(
"foamRockDensity() called but foam is disabled"); }
523 {
throw std::runtime_error(
"foamAdsorbed() called but foam is disabled"); }
Contains the parameters to extend the black-oil model to include the effects of foam.
Declares the properties required by the black oil model.
Scalar foamRockDensity() const
Definition: blackoilfoammodules.hh:519
const Evaluation & foamConcentration() const
Definition: blackoilfoammodules.hh:516
void foamPropertiesUpdate_(const ElementContext &, unsigned, unsigned)
Definition: blackoilfoammodules.hh:511
Scalar foamAdsorbed() const
Definition: blackoilfoammodules.hh:522
Evaluation foamConcentration_
Definition: blackoilfoammodules.hh:498
void foamPropertiesUpdate_(const ElementContext &elemCtx, unsigned dofIdx, unsigned timeIdx)
Update the intensive properties needed to handle polymers from the primary variables.
Definition: blackoilfoammodules.hh:407
const Evaluation & foamAdsorbed() const
Definition: blackoilfoammodules.hh:491
Scalar foamRockDensity() const
Definition: blackoilfoammodules.hh:488
Evaluation foamAdsorbed_
Definition: blackoilfoammodules.hh:500
Implementation & asImp_()
Definition: blackoilfoammodules.hh:495
const Evaluation & foamConcentration() const
Definition: blackoilfoammodules.hh:485
Scalar foamRockDensity_
Definition: blackoilfoammodules.hh:499
Provides the volumetric quantities required for the equations needed by the polymers extension of the...
Definition: blackoilfoammodules.hh:370
Contains the high level supplements required to extend the black oil model to include the effects of ...
Definition: blackoilfoammodules.hh:59
static bool eqApplies(unsigned eqIdx)
Definition: blackoilfoammodules.hh:138
static void registerOutputModules(Model &, Simulator &)
Register all foam specific VTK and ECL output modules.
Definition: blackoilfoammodules.hh:103
static void registerParameters()
Register all run-time parameters for the black-oil foam module.
Definition: blackoilfoammodules.hh:97
static std::string primaryVarName(unsigned pvIdx)
Definition: blackoilfoammodules.hh:124
static Scalar eqWeight(unsigned eqIdx)
Definition: blackoilfoammodules.hh:155
static void deserializeEntity(Model &model, std::istream &instream, const DofEntity &dof)
Definition: blackoilfoammodules.hh:301
static void setParams(BlackOilFoamParams< Scalar > &¶ms)
Set parameters.
Definition: blackoilfoammodules.hh:89
static std::string eqName(unsigned eqIdx)
Definition: blackoilfoammodules.hh:148
static bool primaryVarApplies(unsigned pvIdx)
Definition: blackoilfoammodules.hh:114
static bool foamAllowDesorption(const ElementContext &elemCtx, unsigned scvIdx, unsigned timeIdx)
Definition: blackoilfoammodules.hh:325
static Scalar primaryVarWeight(unsigned pvIdx)
Definition: blackoilfoammodules.hh:130
static OPM_HOST_DEVICE void addStorage(StorageType &storage, const IntensiveQuantities &intQuants)
Definition: blackoilfoammodules.hh:165
static const BlackOilFoamParams< Scalar >::FoamCoefficients & foamCoefficients(const ElementContext &elemCtx, const unsigned scvIdx, const unsigned timeIdx)
Definition: blackoilfoammodules.hh:350
static void computeFlux(RateVector &flux, const ElementContext &elemCtx, unsigned scvfIdx, unsigned timeIdx)
Definition: blackoilfoammodules.hh:207
static Scalar computeUpdateError(const PrimaryVariables &, const EqVector &)
Return how much a Newton-Raphson update is considered an error.
Definition: blackoilfoammodules.hh:280
static const Scalar foamRockDensity(const ElementContext &elemCtx, unsigned scvIdx, unsigned timeIdx)
Definition: blackoilfoammodules.hh:317
static void serializeEntity(const Model &model, std::ostream &outstream, const DofEntity &dof)
Definition: blackoilfoammodules.hh:289
static const TabulatedFunction & adsorbedFoamTable(const ElementContext &elemCtx, unsigned scvIdx, unsigned timeIdx)
Definition: blackoilfoammodules.hh:333
static Phase transportPhase()
Definition: blackoilfoammodules.hh:358
static const TabulatedFunction & gasMobilityMultiplierTable(const ElementContext &elemCtx, unsigned scvIdx, unsigned timeIdx)
Definition: blackoilfoammodules.hh:341
Declare the properties used by the infrastructure code of the finite volume discretizations.
Declare the properties used by the infrastructure code of the finite volume discretizations.
Phase
Phase indices for reservoir coupling, we currently only support black-oil phases (oil,...
Definition: ReservoirCoupling.hpp:156
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
Definition: blackoilfoamparams.hpp:60
Struct holding the parameters for the BlackoilFoamModule class.
Definition: blackoilfoamparams.hpp:44
Tabulated1DFunction< Scalar > TabulatedFunction
Definition: blackoilfoamparams.hpp:45