76 using TabulatedFunction =
typename BlackOilFoamParams<Scalar>::TabulatedFunction;
78 static constexpr unsigned foamConcentrationIdx = Indices::foamConcentrationIdx;
79 static constexpr unsigned contiFoamEqIdx = Indices::contiFoamEqIdx;
80 static constexpr unsigned gasPhaseIdx = FluidSystem::gasPhaseIdx;
81 static constexpr unsigned waterPhaseIdx = FluidSystem::waterPhaseIdx;
86 static constexpr unsigned numPhases = FluidSystem::numPhases;
110 if constexpr (enableFoam) {
111 if (Parameters::Get<Parameters::EnableVtkOutput>()) {
112 OpmLog::warning(
"VTK output requested, currently unsupported by the foam module.");
118 static bool primaryVarApplies(
unsigned pvIdx)
120 if constexpr (enableFoam)
121 return pvIdx == foamConcentrationIdx;
129 return "foam_concentration";
137 return static_cast<Scalar
>(1.0);
140 static bool eqApplies(
unsigned eqIdx)
142 if constexpr (enableFoam)
143 return eqIdx == contiFoamEqIdx;
161 return static_cast<Scalar
>(1.0);
165 template <
class LhsEval>
166 static void addStorage(Dune::FieldVector<LhsEval, numEq>&
storage,
169 if constexpr (enableFoam) {
173 if (params_.transport_phase_ == Phase::WATER) {
176 }
else if (params_.transport_phase_ == Phase::GAS) {
179 }
else if (params_.transport_phase_ == Phase::SOLVENT) {
180 if constexpr (enableSolvent) {
185 throw std::runtime_error(
"Transport phase is GAS/WATER/SOLVENT");
212 if constexpr (enableFoam) {
219 switch (transportPhase()) {
224 flux[contiFoamEqIdx] =
226 *
up.fluidState().invB(waterPhaseIdx)
227 *
up.foamConcentration();
229 flux[contiFoamEqIdx] =
240 flux[contiFoamEqIdx] =
242 *
up.fluidState().invB(gasPhaseIdx)
243 *
up.foamConcentration();
245 flux[contiFoamEqIdx] =
252 case Phase::SOLVENT: {
253 if constexpr (enableSolvent) {
257 flux[contiFoamEqIdx] =
259 *
up.solventInverseFormationVolumeFactor()
260 *
up.foamConcentration();
262 flux[contiFoamEqIdx] =
268 throw std::runtime_error(
"Foam transport phase is SOLVENT but SOLVENT is not activated.");
273 throw std::runtime_error(
"Foam transport phase must be GAS/WATER/SOLVENT.");
287 return static_cast<Scalar
>(0.0);
290 template <
class DofEntity>
291 static void serializeEntity([[
maybe_unused]]
const Model& model,
295 if constexpr (enableFoam) {
296 unsigned dofIdx = model.dofMapper().index(
dof);
297 const PrimaryVariables& priVars = model.solution(0)[
dofIdx];
298 outstream << priVars[foamConcentrationIdx];
302 template <
class DofEntity>
303 static void deserializeEntity([[
maybe_unused]] Model& model,
307 if constexpr (enableFoam) {
308 unsigned dofIdx = model.dofMapper().index(
dof);
319 static const Scalar foamRockDensity(
const ElementContext&
elemCtx,
327 static bool foamAllowDesorption(
const ElementContext&
elemCtx,
335 static const TabulatedFunction& adsorbedFoamTable(
const ElementContext&
elemCtx,
343 static const TabulatedFunction& gasMobilityMultiplierTable(
const ElementContext&
elemCtx,
351 static const typename BlackOilFoamParams<Scalar>::FoamCoefficients&
352 foamCoefficients(
const ElementContext&
elemCtx,
360 static Phase transportPhase() {
361 return params_.transport_phase_;
397 static constexpr int foamConcentrationIdx = Indices::foamConcentrationIdx;
398 static constexpr unsigned waterPhaseIdx = FluidSystem::waterPhaseIdx;
399 static constexpr unsigned oilPhaseIdx = FluidSystem::oilPhaseIdx;
400 static constexpr int gasPhaseIdx = FluidSystem::gasPhaseIdx;
414 foamConcentration_ = priVars.makeEvaluation(foamConcentrationIdx,
timeIdx);
415 const auto&
fs = asImp_().fluidState_;
425 const Scalar fm_mob = foamCoefficients.fm_mob;
427 const Scalar fm_surf = foamCoefficients.fm_surf;
428 const Scalar ep_surf = foamCoefficients.ep_surf;
430 const Scalar fm_oil = foamCoefficients.fm_oil;
431 const Scalar fl_oil = foamCoefficients.fl_oil;
432 const Scalar ep_oil = foamCoefficients.ep_oil;
434 const Scalar fm_dry = foamCoefficients.fm_dry;
435 const Scalar ep_dry = foamCoefficients.ep_dry;
437 const Scalar fm_cap = foamCoefficients.fm_cap;
438 const Scalar ep_cap = foamCoefficients.ep_cap;
440 const Evaluation
C_surf = foamConcentration_;
441 const Evaluation
Ca = 1
e10;
442 const Evaluation
S_o =
fs.saturation(oilPhaseIdx);
443 const Evaluation
S_w =
fs.saturation(waterPhaseIdx);
446 Evaluation
F2 =
pow((fm_oil-
S_o)/(fm_oil-fl_oil), ep_oil);
447 Evaluation
F3 =
pow(fm_cap/
Ca, ep_cap);
460 switch (FoamModule::transportPhase()) {
469 case Phase::SOLVENT: {
470 if constexpr (enableSolvent) {
473 throw std::runtime_error(
"Foam transport phase is SOLVENT but SOLVENT is not activated.");
478 throw std::runtime_error(
"Foam transport phase must be GAS/WATER/SOLVENT.");
485 foamAdsorbed_ = adsorbedFoamTable.eval(foamConcentration_,
true);
487 throw std::runtime_error(
"Foam module does not support the 'no desorption' option.");
491 const Evaluation& foamConcentration()
const
492 {
return foamConcentration_; }
494 Scalar foamRockDensity()
const
495 {
return foamRockDensity_; }
497 const Evaluation& foamAdsorbed()
const
498 {
return foamAdsorbed_; }
501 Implementation& asImp_()
502 {
return *
static_cast<Implementation*
>(
this); }
504 Evaluation foamConcentration_;
505 Scalar foamRockDensity_;
506 Evaluation foamAdsorbed_;
void foamPropertiesUpdate_(const ElementContext &elemCtx, unsigned dofIdx, unsigned timeIdx)
Update the intensive properties needed to handle polymers from the primary variables.
Definition blackoilfoammodules.hh:409
static void registerOutputModules(Model &, Simulator &)
Register all foam specific VTK and ECL output modules.
Definition blackoilfoammodules.hh:107
static Scalar computeUpdateError(const PrimaryVariables &, const EqVector &)
Return how much a Newton-Raphson update is considered an error.
Definition blackoilfoammodules.hh:282
constexpr auto getPropValue()
get the value data member of a property
Definition propertysystem.hh:242
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:235