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>
35#include <opm/input/eclipse/EclipseState/Phase.hpp>
56template <class TypeTag, bool enableFoamV = getPropValue<TypeTag, Properties::EnableFoam>()>
71 using Toolbox = MathToolbox<Evaluation>;
75 static constexpr unsigned foamConcentrationIdx = Indices::foamConcentrationIdx;
76 static constexpr unsigned contiFoamEqIdx = Indices::contiFoamEqIdx;
77 static constexpr unsigned gasPhaseIdx = FluidSystem::gasPhaseIdx;
78 static constexpr unsigned waterPhaseIdx = FluidSystem::waterPhaseIdx;
80 static constexpr unsigned enableFoam = enableFoamV;
82 static constexpr unsigned numEq = getPropValue<TypeTag, Properties::NumEq>();
84 enum { enableSolvent = getPropValue<TypeTag, Properties::EnableSolvent>() };
105 if constexpr (enableFoam) {
106 if (Parameters::Get<Parameters::EnableVtkOutput>()) {
107 OpmLog::warning(
"VTK output requested, currently unsupported by the foam module.");
115 if constexpr (enableFoam) {
116 return pvIdx == foamConcentrationIdx;
126 return "foam_concentration";
134 return static_cast<Scalar
>(1.0);
139 if constexpr (enableFoam) {
140 return eqIdx == contiFoamEqIdx;
147 static std::string
eqName([[maybe_unused]]
unsigned eqIdx)
154 static Scalar
eqWeight([[maybe_unused]]
unsigned eqIdx)
159 return static_cast<Scalar
>(1.0);
163 template <
class LhsEval>
164 static void addStorage(Dune::FieldVector<LhsEval, numEq>& storage,
165 const IntensiveQuantities& intQuants)
167 if constexpr (enableFoam) {
168 const auto& fs = intQuants.fluidState();
170 LhsEval surfaceVolume = Toolbox::template decay<LhsEval>(intQuants.porosity());
171 if (params_.transport_phase_ == Phase::WATER) {
172 surfaceVolume *= Toolbox::template decay<LhsEval>(fs.saturation(waterPhaseIdx)) *
173 Toolbox::template decay<LhsEval>(fs.invB(waterPhaseIdx));
174 }
else if (params_.transport_phase_ == Phase::GAS) {
175 surfaceVolume *= Toolbox::template decay<LhsEval>(fs.saturation(gasPhaseIdx)) *
176 Toolbox::template decay<LhsEval>(fs.invB(gasPhaseIdx));
177 }
else if (params_.transport_phase_ == Phase::SOLVENT) {
178 if constexpr (enableSolvent) {
179 surfaceVolume *= Toolbox::template decay<LhsEval>( intQuants.solventSaturation()) *
180 Toolbox::template decay<LhsEval>(intQuants.solventInverseFormationVolumeFactor());
183 throw std::runtime_error(
"Transport phase is GAS/WATER/SOLVENT");
187 surfaceVolume = max(surfaceVolume, 1e-10);
190 const LhsEval freeFoam = surfaceVolume *
191 Toolbox::template decay<LhsEval>(intQuants.foamConcentration());
194 const LhsEval adsorbedFoam =
195 Toolbox::template decay<LhsEval>(1.0 - intQuants.porosity()) *
196 Toolbox::template decay<LhsEval>(intQuants.foamRockDensity()) *
197 Toolbox::template decay<LhsEval>(intQuants.foamAdsorbed());
199 const LhsEval accumulationFoam = freeFoam + adsorbedFoam;
200 storage[contiFoamEqIdx] += accumulationFoam;
205 [[maybe_unused]]
const ElementContext& elemCtx,
206 [[maybe_unused]]
unsigned scvfIdx,
207 [[maybe_unused]]
unsigned timeIdx)
209 if constexpr (enableFoam) {
210 const auto& extQuants = elemCtx.extensiveQuantities(scvfIdx, timeIdx);
211 const unsigned inIdx = extQuants.interiorIndex();
218 const unsigned upIdx = extQuants.upstreamIndex(waterPhaseIdx);
219 const auto& up = elemCtx.intensiveQuantities(upIdx, timeIdx);
220 if (upIdx == inIdx) {
221 flux[contiFoamEqIdx] =
222 extQuants.volumeFlux(waterPhaseIdx) *
223 up.fluidState().invB(waterPhaseIdx) *
224 up.foamConcentration();
226 flux[contiFoamEqIdx] =
227 extQuants.volumeFlux(waterPhaseIdx) *
228 decay<Scalar>(up.fluidState().invB(waterPhaseIdx)) *
229 decay<Scalar>(up.foamConcentration());
234 const unsigned upIdx = extQuants.upstreamIndex(gasPhaseIdx);
235 const auto& up = elemCtx.intensiveQuantities(upIdx, timeIdx);
236 if (upIdx == inIdx) {
237 flux[contiFoamEqIdx] =
238 extQuants.volumeFlux(gasPhaseIdx) *
239 up.fluidState().invB(gasPhaseIdx) *
240 up.foamConcentration();
242 flux[contiFoamEqIdx] =
243 extQuants.volumeFlux(gasPhaseIdx) *
244 decay<Scalar>(up.fluidState().invB(gasPhaseIdx)) *
245 decay<Scalar>(up.foamConcentration());
250 if constexpr (enableSolvent) {
251 const unsigned upIdx = extQuants.solventUpstreamIndex();
252 const auto& up = elemCtx.intensiveQuantities(upIdx, timeIdx);
253 if (upIdx == inIdx) {
254 flux[contiFoamEqIdx] =
255 extQuants.solventVolumeFlux() *
256 up.solventInverseFormationVolumeFactor() *
257 up.foamConcentration();
259 flux[contiFoamEqIdx] =
260 extQuants.solventVolumeFlux() *
261 decay<Scalar>(up.solventInverseFormationVolumeFactor()) *
262 decay<Scalar>(up.foamConcentration());
265 throw std::runtime_error(
"Foam transport phase is SOLVENT but SOLVENT is not activated.");
269 throw std::runtime_error(
"Foam transport phase must be GAS/WATER/SOLVENT.");
282 return static_cast<Scalar
>(0.0);
285 template <
class DofEntity>
287 [[maybe_unused]] std::ostream& outstream,
288 [[maybe_unused]]
const DofEntity& dof)
290 if constexpr (enableFoam) {
291 const unsigned dofIdx = model.dofMapper().index(dof);
292 const PrimaryVariables& priVars = model.solution(0)[dofIdx];
293 outstream << priVars[foamConcentrationIdx];
297 template <
class DofEntity>
299 [[maybe_unused]] std::istream& instream,
300 [[maybe_unused]]
const DofEntity& dof)
302 if constexpr (enableFoam) {
303 const unsigned dofIdx = model.dofMapper().index(dof);
304 PrimaryVariables& priVars0 = model.solution(0)[dofIdx];
305 PrimaryVariables& priVars1 = model.solution(1)[dofIdx];
307 instream >> priVars0[foamConcentrationIdx];
310 priVars1[foamConcentrationIdx] = priVars0[foamConcentrationIdx];
318 const unsigned satnumRegionIdx = elemCtx.problem().satnumRegionIndex(elemCtx, scvIdx, timeIdx);
319 return params_.foamRockDensity_[satnumRegionIdx];
326 const unsigned satnumRegionIdx = elemCtx.problem().satnumRegionIndex(elemCtx, scvIdx, timeIdx);
327 return params_.foamAllowDesorption_[satnumRegionIdx];
334 const unsigned satnumRegionIdx = elemCtx.problem().satnumRegionIndex(elemCtx, scvIdx, timeIdx);
335 return params_.adsorbedFoamTable_[satnumRegionIdx];
342 const unsigned pvtnumRegionIdx = elemCtx.problem().pvtRegionIndex(elemCtx, scvIdx, timeIdx);
343 return params_.gasMobilityMultiplierTable_[pvtnumRegionIdx];
348 const unsigned scvIdx,
349 const unsigned timeIdx)
351 const unsigned satnumRegionIdx = elemCtx.problem().satnumRegionIndex(elemCtx, scvIdx, timeIdx);
352 return params_.foamCoefficients_[satnumRegionIdx];
356 {
return params_.transport_phase_; }
362template <
class TypeTag,
bool enableFoam>
363BlackOilFoamParams<typename BlackOilFoamModule<TypeTag, enableFoam>::Scalar>
364BlackOilFoamModule<TypeTag, enableFoam>::params_;
366template <
class TypeTag,
bool enableFoam>
376template <
class TypeTag>
391 enum { enableSolvent = getPropValue<TypeTag, Properties::EnableSolvent>() };
393 static constexpr int foamConcentrationIdx = Indices::foamConcentrationIdx;
394 static constexpr unsigned waterPhaseIdx = FluidSystem::waterPhaseIdx;
395 static constexpr unsigned oilPhaseIdx = FluidSystem::oilPhaseIdx;
396 static constexpr int gasPhaseIdx = FluidSystem::gasPhaseIdx;
408 const PrimaryVariables& priVars = elemCtx.primaryVars(dofIdx, timeIdx);
409 foamConcentration_ = priVars.makeEvaluation(foamConcentrationIdx, timeIdx);
410 const auto& fs = asImp_().fluidState_;
413 Evaluation mobilityReductionFactor = 1.0;
414 if constexpr (
false) {
418 const auto& foamCoefficients = FoamModule::foamCoefficients(elemCtx, dofIdx, timeIdx);
420 const Scalar fm_mob = foamCoefficients.fm_mob;
422 const Scalar fm_surf = foamCoefficients.fm_surf;
423 const Scalar ep_surf = foamCoefficients.ep_surf;
425 const Scalar fm_oil = foamCoefficients.fm_oil;
426 const Scalar fl_oil = foamCoefficients.fl_oil;
427 const Scalar ep_oil = foamCoefficients.ep_oil;
429 const Scalar fm_dry = foamCoefficients.fm_dry;
430 const Scalar ep_dry = foamCoefficients.ep_dry;
432 const Scalar fm_cap = foamCoefficients.fm_cap;
433 const Scalar ep_cap = foamCoefficients.ep_cap;
435 const Evaluation C_surf = foamConcentration_;
436 const Evaluation Ca = 1e10;
437 const Evaluation S_o = fs.saturation(oilPhaseIdx);
438 const Evaluation S_w = fs.saturation(waterPhaseIdx);
440 const Evaluation F1 = pow(C_surf / fm_surf, ep_surf);
441 const Evaluation F2 = pow((fm_oil - S_o) / (fm_oil - fl_oil), ep_oil);
442 const Evaluation F3 = pow(fm_cap / Ca, ep_cap);
443 const Evaluation F7 = 0.5 + atan(ep_dry * (S_w - fm_dry)) / M_PI;
445 mobilityReductionFactor = 1. / (1. + fm_mob * F1 * F2 * F3 * F7);
450 const auto& gasMobilityMultiplier = FoamModule::gasMobilityMultiplierTable(elemCtx, dofIdx, timeIdx);
451 mobilityReductionFactor = gasMobilityMultiplier.eval(foamConcentration_,
true);
455 switch (FoamModule::transportPhase()) {
457 asImp_().mobility_[waterPhaseIdx] *= mobilityReductionFactor;
460 asImp_().mobility_[gasPhaseIdx] *= mobilityReductionFactor;
463 if constexpr (enableSolvent) {
464 asImp_().solventMobility_ *= mobilityReductionFactor;
466 throw std::runtime_error(
"Foam transport phase is SOLVENT but SOLVENT is not activated.");
470 throw std::runtime_error(
"Foam transport phase must be GAS/WATER/SOLVENT.");
473 foamRockDensity_ = FoamModule::foamRockDensity(elemCtx, dofIdx, timeIdx);
475 const auto& adsorbedFoamTable = FoamModule::adsorbedFoamTable(elemCtx, dofIdx, timeIdx);
476 foamAdsorbed_ = adsorbedFoamTable.eval(foamConcentration_,
true);
477 if (!FoamModule::foamAllowDesorption(elemCtx, dofIdx, timeIdx)) {
478 throw std::runtime_error(
"Foam module does not support the 'no desorption' option.");
483 {
return foamConcentration_; }
486 {
return foamRockDensity_; }
489 {
return foamAdsorbed_; }
493 {
return *
static_cast<Implementation*
>(
this); }
500template <
class TypeTag>
514 {
throw std::runtime_error(
"foamConcentration() called but foam is disabled"); }
517 {
throw std::runtime_error(
"foamRockDensity() called but foam is disabled"); }
520 {
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:516
const Evaluation & foamConcentration() const
Definition: blackoilfoammodules.hh:513
void foamPropertiesUpdate_(const ElementContext &, unsigned, unsigned)
Definition: blackoilfoammodules.hh:508
Scalar foamAdsorbed() const
Definition: blackoilfoammodules.hh:519
Evaluation foamConcentration_
Definition: blackoilfoammodules.hh:495
void foamPropertiesUpdate_(const ElementContext &elemCtx, unsigned dofIdx, unsigned timeIdx)
Update the intensive properties needed to handle polymers from the primary variables.
Definition: blackoilfoammodules.hh:404
const Evaluation & foamAdsorbed() const
Definition: blackoilfoammodules.hh:488
Scalar foamRockDensity() const
Definition: blackoilfoammodules.hh:485
Evaluation foamAdsorbed_
Definition: blackoilfoammodules.hh:497
Implementation & asImp_()
Definition: blackoilfoammodules.hh:492
const Evaluation & foamConcentration() const
Definition: blackoilfoammodules.hh:482
Scalar foamRockDensity_
Definition: blackoilfoammodules.hh:496
Provides the volumetric quantities required for the equations needed by the polymers extension of the...
Definition: blackoilfoammodules.hh:367
Contains the high level supplements required to extend the black oil model to include the effects of ...
Definition: blackoilfoammodules.hh:58
static bool eqApplies(unsigned eqIdx)
Definition: blackoilfoammodules.hh:137
static void registerOutputModules(Model &, Simulator &)
Register all foam specific VTK and ECL output modules.
Definition: blackoilfoammodules.hh:102
static void registerParameters()
Register all run-time parameters for the black-oil foam module.
Definition: blackoilfoammodules.hh:96
static std::string primaryVarName(unsigned pvIdx)
Definition: blackoilfoammodules.hh:123
static Scalar eqWeight(unsigned eqIdx)
Definition: blackoilfoammodules.hh:154
static void deserializeEntity(Model &model, std::istream &instream, const DofEntity &dof)
Definition: blackoilfoammodules.hh:298
static void setParams(BlackOilFoamParams< Scalar > &¶ms)
Set parameters.
Definition: blackoilfoammodules.hh:88
static std::string eqName(unsigned eqIdx)
Definition: blackoilfoammodules.hh:147
static bool primaryVarApplies(unsigned pvIdx)
Definition: blackoilfoammodules.hh:113
static void addStorage(Dune::FieldVector< LhsEval, numEq > &storage, const IntensiveQuantities &intQuants)
Definition: blackoilfoammodules.hh:164
static bool foamAllowDesorption(const ElementContext &elemCtx, unsigned scvIdx, unsigned timeIdx)
Definition: blackoilfoammodules.hh:322
static Scalar primaryVarWeight(unsigned pvIdx)
Definition: blackoilfoammodules.hh:129
static const BlackOilFoamParams< Scalar >::FoamCoefficients & foamCoefficients(const ElementContext &elemCtx, const unsigned scvIdx, const unsigned timeIdx)
Definition: blackoilfoammodules.hh:347
static void computeFlux(RateVector &flux, const ElementContext &elemCtx, unsigned scvfIdx, unsigned timeIdx)
Definition: blackoilfoammodules.hh:204
static Scalar computeUpdateError(const PrimaryVariables &, const EqVector &)
Return how much a Newton-Raphson update is considered an error.
Definition: blackoilfoammodules.hh:277
static const Scalar foamRockDensity(const ElementContext &elemCtx, unsigned scvIdx, unsigned timeIdx)
Definition: blackoilfoammodules.hh:314
static void serializeEntity(const Model &model, std::ostream &outstream, const DofEntity &dof)
Definition: blackoilfoammodules.hh:286
static const TabulatedFunction & adsorbedFoamTable(const ElementContext &elemCtx, unsigned scvIdx, unsigned timeIdx)
Definition: blackoilfoammodules.hh:330
static Phase transportPhase()
Definition: blackoilfoammodules.hh:355
static const TabulatedFunction & gasMobilityMultiplierTable(const ElementContext &elemCtx, unsigned scvIdx, unsigned timeIdx)
Definition: blackoilfoammodules.hh:338
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:141
Definition: blackoilbioeffectsmodules.hh:43
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:64
Struct holding the parameters for the BlackoilFoamModule class.
Definition: blackoilfoamparams.hpp:46
Tabulated1DFunction< Scalar > TabulatedFunction
Definition: blackoilfoamparams.hpp:47