28 #ifndef EWOMS_BLACK_OIL_SOLVENT_MODULE_HH 29 #define EWOMS_BLACK_OIL_SOLVENT_MODULE_HH 31 #include <dune/common/fvector.hh> 33 #include <opm/common/Exceptions.hpp> 34 #include <opm/common/utility/gpuDecorators.hpp> 36 #include <opm/material/common/MathToolbox.hpp> 37 #include <opm/material/common/Valgrind.hpp> 38 #include <opm/material/fluidsystems/blackoilpvt/SolventPvt.hpp> 67 template <
class TypeTag>
68 class BlackOilSolventModule<TypeTag, true>
81 using Toolbox = MathToolbox<Evaluation>;
82 using SolventPvt =
typename BlackOilSolventParams<Scalar>::SolventPvt;
83 using Co2GasPvt =
typename BlackOilSolventParams<Scalar>::Co2GasPvt;
84 using H2GasPvt =
typename BlackOilSolventParams<Scalar>::H2GasPvt;
85 using BrineCo2Pvt =
typename BlackOilSolventParams<Scalar>::BrineCo2Pvt;
86 using BrineH2Pvt =
typename BlackOilSolventParams<Scalar>::BrineH2Pvt;
88 using TabulatedFunction =
typename BlackOilSolventParams<Scalar>::TabulatedFunction;
90 static constexpr
unsigned solventSaturationIdx = Indices::solventSaturationIdx;
91 static constexpr
unsigned contiSolventEqIdx = Indices::contiSolventEqIdx;
92 static constexpr
unsigned enableSolvent =
true;
93 static constexpr
unsigned numEq = getPropValue<TypeTag, Properties::NumEq>();
94 static constexpr
bool blackoilConserveSurfaceVolume =
95 getPropValue<TypeTag, Properties::BlackoilConserveSurfaceVolume>();
96 static constexpr
int waterPhaseIdx = FluidSystem::waterPhaseIdx;
99 static constexpr
double cutOff = 1e-12;
102 { params_ = params; }
108 { params_.solventPvt_ = value; }
110 static void setIsMiscible(
const bool isMiscible)
111 { params_.isMiscible_ = isMiscible; }
125 Simulator& simulator)
130 static bool primaryVarApplies(
unsigned pvIdx)
132 return pvIdx == solventSaturationIdx;
135 static std::string primaryVarName([[maybe_unused]]
unsigned pvIdx)
137 assert(primaryVarApplies(pvIdx));
139 return "saturation_solvent";
142 static Scalar primaryVarWeight([[maybe_unused]]
unsigned pvIdx)
144 assert(primaryVarApplies(pvIdx));
147 return static_cast<Scalar
>(1.0);
150 static bool eqApplies(
unsigned eqIdx)
152 return eqIdx == contiSolventEqIdx;
155 static std::string eqName([[maybe_unused]]
unsigned eqIdx)
157 assert(eqApplies(eqIdx));
159 return "conti^solvent";
162 static Scalar eqWeight([[maybe_unused]]
unsigned eqIdx)
164 assert(eqApplies(eqIdx));
167 return static_cast<Scalar
>(1.0);
170 template <
class StorageType>
171 OPM_HOST_DEVICE
static void addStorage(StorageType& storage,
172 const IntensiveQuantities& intQuants)
174 using LhsEval =
typename StorageType::value_type;
176 if constexpr (blackoilConserveSurfaceVolume) {
177 storage[contiSolventEqIdx] +=
178 Toolbox::template decay<LhsEval>(intQuants.porosity()) *
179 Toolbox::template decay<LhsEval>(intQuants.solventSaturation()) *
180 Toolbox::template decay<LhsEval>(intQuants.solventInverseFormationVolumeFactor());
181 if (isSolubleInWater()) {
182 storage[contiSolventEqIdx] +=
183 Toolbox::template decay<LhsEval>(intQuants.porosity()) *
184 Toolbox::template decay<LhsEval>(intQuants.fluidState().saturation(waterPhaseIdx)) *
185 Toolbox::template decay<LhsEval>(intQuants.fluidState().invB(waterPhaseIdx)) *
186 Toolbox::template decay<LhsEval>(intQuants.rsSolw());
190 storage[contiSolventEqIdx] +=
191 Toolbox::template decay<LhsEval>(intQuants.porosity()) *
192 Toolbox::template decay<LhsEval>(intQuants.solventSaturation()) *
193 Toolbox::template decay<LhsEval>(intQuants.solventDensity());
194 if (isSolubleInWater()) {
195 storage[contiSolventEqIdx] +=
196 Toolbox::template decay<LhsEval>(intQuants.porosity()) *
197 Toolbox::template decay<LhsEval>(intQuants.fluidState().saturation(waterPhaseIdx)) *
198 Toolbox::template decay<LhsEval>(intQuants.fluidState().density(waterPhaseIdx)) *
199 Toolbox::template decay<LhsEval>(intQuants.rsSolw());
204 static void computeFlux(RateVector& flux,
205 const ElementContext& elemCtx,
210 const auto& extQuants = elemCtx.extensiveQuantities(scvfIdx, timeIdx);
212 const unsigned upIdx = extQuants.solventUpstreamIndex();
213 const unsigned inIdx = extQuants.interiorIndex();
214 const auto& up = elemCtx.intensiveQuantities(upIdx, timeIdx);
216 if constexpr (blackoilConserveSurfaceVolume) {
217 if (upIdx == inIdx) {
218 flux[contiSolventEqIdx] = extQuants.solventVolumeFlux() *
219 up.solventInverseFormationVolumeFactor();
222 flux[contiSolventEqIdx] = extQuants.solventVolumeFlux() *
223 decay<Scalar>(up.solventInverseFormationVolumeFactor());
227 if (isSolubleInWater()) {
228 if (upIdx == inIdx) {
229 flux[contiSolventEqIdx] +=
230 extQuants.volumeFlux(waterPhaseIdx) *
231 up.fluidState().invB(waterPhaseIdx) *
235 flux[contiSolventEqIdx] +=
236 extQuants.volumeFlux(waterPhaseIdx) *
237 decay<Scalar>(up.fluidState().invB(waterPhaseIdx)) *
238 decay<Scalar>(up.rsSolw());
243 if (upIdx == inIdx) {
244 flux[contiSolventEqIdx] = extQuants.solventVolumeFlux() * up.solventDensity();
247 flux[contiSolventEqIdx] = extQuants.solventVolumeFlux() * decay<Scalar>(up.solventDensity());
250 if (isSolubleInWater()) {
251 if (upIdx == inIdx) {
252 flux[contiSolventEqIdx] +=
253 extQuants.volumeFlux(waterPhaseIdx) *
254 up.fluidState().density(waterPhaseIdx) *
258 flux[contiSolventEqIdx] +=
259 extQuants.volumeFlux(waterPhaseIdx) *
260 decay<Scalar>(up.fluidState().density(waterPhaseIdx)) *
261 decay<Scalar>(up.rsSolw());
271 Scalar solventSaturation,
275 if (solventSaturation > 0 || !isSolubleInWater()) {
276 priVars.setPrimaryVarsMeaningSolvent(PrimaryVariables::SolventMeaning::Ss);
277 priVars[solventSaturationIdx] = solventSaturation;
279 priVars.setPrimaryVarsMeaningSolvent(PrimaryVariables::SolventMeaning::Rsolw);
280 priVars[solventSaturationIdx] = solventRsw;
288 const PrimaryVariables& oldPv,
289 const EqVector& delta)
292 newPv[solventSaturationIdx] = oldPv[solventSaturationIdx] - delta[solventSaturationIdx];
304 return static_cast<Scalar
>(0.0);
313 return std::abs(Toolbox::scalarValue(resid[contiSolventEqIdx]));
316 template <
class DofEntity>
317 static void serializeEntity(
const Model& model, std::ostream& outstream,
const DofEntity& dof)
319 const unsigned dofIdx = model.dofMapper().index(dof);
321 const PrimaryVariables& priVars = model.solution(0)[dofIdx];
322 outstream << priVars[solventSaturationIdx];
325 template <
class DofEntity>
326 static void deserializeEntity(Model& model, std::istream& instream,
const DofEntity& dof)
328 const unsigned dofIdx = model.dofMapper().index(dof);
330 PrimaryVariables& priVars0 = model.solution(0)[dofIdx];
331 PrimaryVariables& priVars1 = model.solution(1)[dofIdx];
333 instream >> priVars0[solventSaturationIdx];
336 priVars1 = priVars0[solventSaturationIdx];
339 static const SolventPvt& solventPvt()
340 {
return params_.solventPvt_; }
342 static const Co2GasPvt& co2GasPvt()
343 {
return params_.co2GasPvt_; }
345 static const H2GasPvt& h2GasPvt()
346 {
return params_.h2GasPvt_; }
348 static const BrineCo2Pvt& brineCo2Pvt()
349 {
return params_.brineCo2Pvt_; }
351 static const BrineH2Pvt& brineH2Pvt()
352 {
return params_.brineH2Pvt_; }
354 template <
class ElemContext>
355 static const TabulatedFunction& ssfnKrg(
const ElemContext& elemCtx,
359 const unsigned satnumRegionIdx =
360 elemCtx.problem().satnumRegionIndex(elemCtx, scvIdx, timeIdx);
361 return params_.ssfnKrg_[satnumRegionIdx];
364 template <
class ElemContext>
365 static const TabulatedFunction& ssfnKrs(
const ElemContext& elemCtx,
369 const unsigned satnumRegionIdx =
370 elemCtx.problem().satnumRegionIndex(elemCtx, scvIdx, timeIdx);
371 return params_.ssfnKrs_[satnumRegionIdx];
374 static const TabulatedFunction& ssfnKrg(
const unsigned satnumRegionIdx)
376 return params_.ssfnKrg_[satnumRegionIdx];
379 static const TabulatedFunction& ssfnKrs(
const unsigned satnumRegionIdx)
381 return params_.ssfnKrs_[satnumRegionIdx];
384 template <
class ElemContext>
385 static const TabulatedFunction& sof2Krn(
const ElemContext& elemCtx,
389 const unsigned satnumRegionIdx =
390 elemCtx.problem().satnumRegionIndex(elemCtx, scvIdx, timeIdx);
391 return params_.sof2Krn_[satnumRegionIdx];
394 template <
class ElemContext>
395 static const TabulatedFunction& misc(
const ElemContext& elemCtx,
399 const unsigned miscnumRegionIdx =
400 elemCtx.problem().miscnumRegionIndex(elemCtx, scvIdx, timeIdx);
401 return params_.misc_[miscnumRegionIdx];
404 template <
class ElemContext>
405 static const TabulatedFunction& pmisc(
const ElemContext& elemCtx,
409 const unsigned miscnumRegionIdx =
410 elemCtx.problem().miscnumRegionIndex(elemCtx, scvIdx, timeIdx);
411 return params_.pmisc_[miscnumRegionIdx];
414 template <
class ElemContext>
415 static const TabulatedFunction& msfnKrsg(
const ElemContext& elemCtx,
419 const unsigned satnumRegionIdx =
420 elemCtx.problem().satnumRegionIndex(elemCtx, scvIdx, timeIdx);
421 return params_.msfnKrsg_[satnumRegionIdx];
424 template <
class ElemContext>
425 static const TabulatedFunction& msfnKro(
const ElemContext& elemCtx,
429 const unsigned satnumRegionIdx =
430 elemCtx.problem().satnumRegionIndex(elemCtx, scvIdx, timeIdx);
431 return params_.msfnKro_[satnumRegionIdx];
434 template <
class ElemContext>
435 static const TabulatedFunction& sorwmis(
const ElemContext& elemCtx,
439 const unsigned miscnumRegionIdx =
440 elemCtx.problem().miscnumRegionIndex(elemCtx, scvIdx, timeIdx);
441 return params_.sorwmis_[miscnumRegionIdx];
444 template <
class ElemContext>
445 static const TabulatedFunction& sgcwmis(
const ElemContext& elemCtx,
449 const unsigned miscnumRegionIdx =
450 elemCtx.problem().miscnumRegionIndex(elemCtx, scvIdx, timeIdx);
451 return params_.sgcwmis_[miscnumRegionIdx];
454 template <
class ElemContext>
455 static const TabulatedFunction& tlPMixTable(
const ElemContext& elemCtx,
459 const unsigned miscnumRegionIdx =
460 elemCtx.problem().miscnumRegionIndex(elemCtx, scvIdx, timeIdx);
461 return params_.tlPMixTable_[miscnumRegionIdx];
464 template <
class ElemContext>
465 static Scalar tlMixParamViscosity(
const ElemContext& elemCtx,
469 const unsigned miscnumRegionIdx =
470 elemCtx.problem().miscnumRegionIndex(elemCtx, scvIdx, timeIdx);
471 return params_.tlMixParamViscosity_[miscnumRegionIdx];
475 template <
class ElemContext>
476 static Scalar tlMixParamDensity(
const ElemContext& elemCtx,
480 const unsigned miscnumRegionIdx =
481 elemCtx.problem().miscnumRegionIndex(elemCtx, scvIdx, timeIdx);
482 return params_.tlMixParamDensity_[miscnumRegionIdx];
485 static bool isMiscible()
486 {
return params_.isMiscible_; }
488 template <
class Value>
489 static Value solubilityLimit(
unsigned pvtIdx,
const Value& temperature,
490 const Value& pressure,
const Value& saltConcentration)
492 if (!isSolubleInWater()) {
496 assert(isCO2Sol() || isH2Sol());
498 return brineCo2Pvt().saturatedGasDissolutionFactor(pvtIdx, temperature,
499 pressure, saltConcentration);
502 return brineH2Pvt().saturatedGasDissolutionFactor(pvtIdx, temperature,
503 pressure, saltConcentration);
507 static bool isSolubleInWater()
508 {
return params_.rsSolw_active_; }
510 static bool isCO2Sol()
511 {
return params_.co2sol_; }
513 static bool isH2Sol()
514 {
return params_.h2sol_; }
517 static BlackOilSolventParams<Scalar> params_;
520 template <
class TypeTag>
521 BlackOilSolventParams<typename BlackOilSolventModule<TypeTag, true>::Scalar>
522 BlackOilSolventModule<TypeTag, true>::params_;
531 template <
class TypeTag>
547 enum { numPhases = getPropValue<TypeTag, Properties::NumPhases>() };
548 static constexpr
unsigned solventSaturationIdx = Indices::solventSaturationIdx;
549 static constexpr
int oilPhaseIdx = FluidSystem::oilPhaseIdx;
550 static constexpr
int gasPhaseIdx = FluidSystem::gasPhaseIdx;
551 static constexpr
int waterPhaseIdx = FluidSystem::waterPhaseIdx;
552 static constexpr
double cutOff = SolventModule::cutOff;
566 const PrimaryVariables& priVars = elemCtx.primaryVars(dofIdx, timeIdx);
567 this->solventPreSatFuncUpdate_(priVars, timeIdx, elemCtx.linearizationType());
570 void solventPreSatFuncUpdate_(
const PrimaryVariables& priVars,
571 const unsigned timeIdx,
574 auto& fs = asImp_().fluidState_;
575 Evaluation solventSat{0.0};
576 if (priVars.primaryVarsMeaningSolvent() == PrimaryVariables::SolventMeaning::Ss) {
577 solventSat = priVars.makeEvaluation(solventSaturationIdx, timeIdx, linearizationType);
580 fs.setSolventSaturation(solventSat);
582 hydrocarbonSaturation_ = fs.saturation(gasPhaseIdx);
585 if (solventSaturation().value() < cutOff) {
591 fs.setSaturation(gasPhaseIdx, hydrocarbonSaturation_ + solventSat);
605 const PrimaryVariables& priVars = elemCtx.primaryVars(dofIdx, timeIdx);
606 this->solventPostSatFuncUpdate_(elemCtx.problem(),
608 elemCtx.globalSpaceIndex(dofIdx, timeIdx),
610 elemCtx.linearizationType());
615 template <
class Problem>
616 struct ProblemAndCellIndexOnlyContext
618 const Problem& problem_;
620 const Problem& problem()
const {
return problem_; }
621 unsigned int globalSpaceIndex([[maybe_unused]]
const unsigned int spaceIdx,
622 [[maybe_unused]]
const unsigned int timeIdx)
const 629 void solventPostSatFuncUpdate_(
const Problem& problem,
630 const PrimaryVariables& priVars,
631 const unsigned globalSpaceIdx,
632 const unsigned timeIdx,
633 const LinearizationType linearizationType)
637 auto& fs = asImp_().fluidState_;
638 fs.setSaturation(gasPhaseIdx, hydrocarbonSaturation_);
641 Evaluation rsSolw{0.0};
642 if (priVars.primaryVarsMeaningSolvent() == PrimaryVariables::SolventMeaning::Ss) {
643 rsSolw = SolventModule::solubilityLimit(asImp_().pvtRegionIndex(),
644 fs.temperature(waterPhaseIdx),
645 fs.pressure(waterPhaseIdx),
646 fs.saltConcentration());
648 else if (priVars.primaryVarsMeaningSolvent() == PrimaryVariables::SolventMeaning::Rsolw) {
649 rsSolw = priVars.makeEvaluation(solventSaturationIdx, timeIdx, linearizationType);
652 fs.setRsSolw(rsSolw);
654 solventMobility_ = 0.0;
657 if (solventSaturation().value() < cutOff) {
661 ProblemAndCellIndexOnlyContext<Problem> elemCtx{problem, globalSpaceIdx};
665 if (SolventModule::isMiscible()) {
666 const Evaluation& p =
667 FluidSystem::phaseIsActive(oilPhaseIdx)
668 ? fs.pressure(oilPhaseIdx)
669 : fs.pressure(gasPhaseIdx);
670 const Evaluation pmisc =
671 SolventModule::pmisc(elemCtx, dofIdx, timeIdx).eval(p,
true);
672 const Evaluation& pgImisc = fs.pressure(gasPhaseIdx);
675 Evaluation pgMisc = 0.0;
676 std::array<Evaluation, numPhases> pC;
677 const auto& materialParams = problem.materialLawParams(elemCtx, dofIdx, timeIdx);
678 MaterialLaw::capillaryPressures(pC, materialParams, fs);
681 if (priVars.primaryVarsMeaningPressure() == PrimaryVariables::PressureMeaning::Pg) {
682 pgMisc = priVars.makeEvaluation(Indices::pressureSwitchIdx, timeIdx,
686 const Evaluation& po =
687 priVars.makeEvaluation(Indices::pressureSwitchIdx,
688 timeIdx, linearizationType);
689 pgMisc = po + (pC[gasPhaseIdx] - pC[oilPhaseIdx]);
692 fs.setPressure(gasPhaseIdx, pmisc * pgMisc + (1.0 - pmisc) * pgImisc);
695 const Evaluation gasSolventSat = hydrocarbonSaturation_ + solventSaturation();
697 if (gasSolventSat.value() < cutOff) {
701 const Evaluation Fhydgas = hydrocarbonSaturation_ / gasSolventSat;
702 const Evaluation Fsolgas = solventSaturation() / gasSolventSat;
705 if (SolventModule::isMiscible() && FluidSystem::phaseIsActive(oilPhaseIdx)) {
706 const auto& misc = SolventModule::misc(elemCtx, dofIdx, timeIdx);
707 const auto& pmisc = SolventModule::pmisc(elemCtx, dofIdx, timeIdx);
708 const Evaluation& p =
709 FluidSystem::phaseIsActive(oilPhaseIdx)
710 ? fs.pressure(oilPhaseIdx)
711 : fs.pressure(gasPhaseIdx);
712 const Evaluation miscibility =
713 misc.eval(Fsolgas,
true) *
717 const unsigned cellIdx = elemCtx.globalSpaceIndex(dofIdx, timeIdx);
718 const auto& materialLawManager = elemCtx.problem().materialLawManager();
719 const auto& scaledDrainageInfo =
720 materialLawManager->oilWaterScaledEpsInfoDrainage(cellIdx);
722 const Scalar sogcr = scaledDrainageInfo.Sogcr;
723 Evaluation sor = sogcr;
724 if (FluidSystem::phaseIsActive(waterPhaseIdx)) {
725 const Evaluation& sw = fs.saturation(waterPhaseIdx);
726 const auto& sorwmis = SolventModule::sorwmis(elemCtx, dofIdx, timeIdx);
728 sorwmis.eval(sw,
true) + (1.0 - miscibility) * sogcr;
730 const Scalar sgcr = scaledDrainageInfo.Sgcr;
731 Evaluation sgc = sgcr;
732 if (FluidSystem::phaseIsActive(waterPhaseIdx)) {
733 const Evaluation& sw = fs.saturation(waterPhaseIdx);
734 const auto& sgcwmis = SolventModule::sgcwmis(elemCtx, dofIdx, timeIdx);
735 sgc = miscibility * sgcwmis.eval(sw,
true) + (1.0 - miscibility) * sgcr;
738 Evaluation oilGasSolventSat = gasSolventSat;
739 if (FluidSystem::phaseIsActive(oilPhaseIdx)) {
740 oilGasSolventSat += fs.saturation(oilPhaseIdx);
742 const Evaluation zero = 0.0;
743 const Evaluation oilGasSolventEffSat = std::max(oilGasSolventSat - sor - sgc, zero);
745 Evaluation F_totalGas = 0.0;
746 if (oilGasSolventEffSat.value() > cutOff) {
747 const Evaluation gasSolventEffSat = std::max(gasSolventSat - sgc, zero);
748 F_totalGas = gasSolventEffSat / oilGasSolventEffSat;
750 const auto& msfnKro = SolventModule::msfnKro(elemCtx, dofIdx, timeIdx);
751 const auto& msfnKrsg = SolventModule::msfnKrsg(elemCtx, dofIdx, timeIdx);
752 const auto& sof2Krn = SolventModule::sof2Krn(elemCtx, dofIdx, timeIdx);
754 const Evaluation mkrgt = msfnKrsg.eval(F_totalGas,
true) *
755 sof2Krn.eval(oilGasSolventSat,
true);
756 const Evaluation mkro = msfnKro.eval(F_totalGas,
true) *
757 sof2Krn.eval(oilGasSolventSat,
true);
759 Evaluation& kro = asImp_().mobility_[oilPhaseIdx];
760 Evaluation& krg = asImp_().mobility_[gasPhaseIdx];
763 krg *= 1.0 - miscibility;
764 krg += miscibility * mkrgt;
765 kro *= 1.0 - miscibility;
766 kro += miscibility * mkro;
770 const auto& ssfnKrg = SolventModule::ssfnKrg(elemCtx, dofIdx, timeIdx);
771 const auto& ssfnKrs = SolventModule::ssfnKrs(elemCtx, dofIdx, timeIdx);
773 Evaluation& krg = asImp_().mobility_[gasPhaseIdx];
774 solventMobility_ = krg * ssfnKrs.eval(Fsolgas,
true);
775 krg *= ssfnKrg.eval(Fhydgas,
true);
788 const auto& iq = asImp_();
789 auto& fs = asImp_().fluidState_;
790 const unsigned pvtRegionIdx = iq.pvtRegionIndex();
791 const Evaluation& T = iq.fluidState().temperature(gasPhaseIdx);
792 const Evaluation& p = iq.fluidState().pressure(gasPhaseIdx);
794 Evaluation solventInvB;
795 const Evaluation rv = 0.0;
796 const Evaluation rvw = 0.0;
797 if (SolventModule::isCO2Sol() || SolventModule::isH2Sol() ){
798 if (SolventModule::isCO2Sol()) {
799 const auto& co2gasPvt = SolventModule::co2GasPvt();
801 co2gasPvt.inverseFormationVolumeFactor(pvtRegionIdx, T, p, rv, rvw);
802 solventRefDensity_ = co2gasPvt.gasReferenceDensity(pvtRegionIdx);
803 solventViscosity_ = co2gasPvt.viscosity(pvtRegionIdx, T, p, rv, rvw);
805 const auto& brineCo2Pvt = SolventModule::brineCo2Pvt();
806 const auto& bw = brineCo2Pvt.inverseFormationVolumeFactor(pvtRegionIdx, T, p, rsSolw());
808 const auto denw = bw * brineCo2Pvt.waterReferenceDensity(pvtRegionIdx) +
809 rsSolw() * bw * brineCo2Pvt.gasReferenceDensity(pvtRegionIdx);
810 fs.setDensity(waterPhaseIdx, denw);
811 fs.setInvB(waterPhaseIdx, bw);
812 Evaluation& mobw = asImp_().mobility_[waterPhaseIdx];
813 const auto& muWat = fs.viscosity(waterPhaseIdx);
814 const auto& muWatEff = brineCo2Pvt.viscosity(pvtRegionIdx, T, p, rsSolw());
815 mobw *= muWat / muWatEff;
817 const auto& h2gasPvt = SolventModule::h2GasPvt();
819 h2gasPvt.inverseFormationVolumeFactor(pvtRegionIdx, T, p, rv, rvw);
820 solventRefDensity_ = h2gasPvt.gasReferenceDensity(pvtRegionIdx);
821 solventViscosity_ = h2gasPvt.viscosity(pvtRegionIdx, T, p, rv, rvw);
823 const auto& brineH2Pvt = SolventModule::brineH2Pvt();
824 const auto& bw = brineH2Pvt.inverseFormationVolumeFactor(pvtRegionIdx, T, p, rsSolw());
826 const auto denw = bw * brineH2Pvt.waterReferenceDensity(pvtRegionIdx) +
827 rsSolw() * bw * brineH2Pvt.gasReferenceDensity(pvtRegionIdx);
828 fs.setDensity(waterPhaseIdx, denw);
829 fs.setInvB(waterPhaseIdx, bw);
830 Evaluation& mobw = asImp_().mobility_[waterPhaseIdx];
831 const auto& muWat = fs.viscosity(waterPhaseIdx);
832 const auto& muWatEff = brineH2Pvt.viscosity(pvtRegionIdx, T, p, rsSolw());
833 mobw *= muWat / muWatEff;
836 const auto& solventPvt = SolventModule::solventPvt();
837 solventInvB = solventPvt.inverseFormationVolumeFactor(pvtRegionIdx, T, p);
838 solventRefDensity_ = solventPvt.referenceDensity(pvtRegionIdx);
839 solventViscosity_ = solventPvt.viscosity(pvtRegionIdx, T, p);
843 fs.setSolventInvB(solventInvB);
844 fs.setSolventDensity(solventInvB * solventRefDensity_);
846 effectiveProperties(elemCtx, scvIdx, timeIdx);
848 solventMobility_ /= solventViscosity_;
851 Evaluation solventSaturation()
const 852 {
return asImp_().fluidState_.solventSaturation(); }
854 Evaluation rsSolw()
const 855 {
return asImp_().fluidState_.rsSolw(); }
857 Evaluation solventDensity()
const 858 {
return asImp_().fluidState_.solventDensity(); }
860 const Evaluation& solventViscosity()
const 861 {
return solventViscosity_; }
863 const Evaluation& solventMobility()
const 864 {
return solventMobility_; }
866 Evaluation solventInverseFormationVolumeFactor()
const 867 {
return asImp_().fluidState_.solventInvB(); }
870 Scalar solventRefDensity()
const 871 {
return solventRefDensity_; }
876 void effectiveProperties(
const ElementContext& elemCtx,
880 if (!SolventModule::isMiscible()) {
886 if (solventSaturation() < cutOff) {
892 auto& fs = asImp_().fluidState_;
895 Evaluation oilEffSat = 0.0;
896 if (FluidSystem::phaseIsActive(oilPhaseIdx)) {
897 oilEffSat = fs.saturation(oilPhaseIdx);
899 Evaluation gasEffSat = fs.saturation(gasPhaseIdx);
900 Evaluation solventEffSat = solventSaturation();
901 if (FluidSystem::phaseIsActive(waterPhaseIdx)) {
902 const auto& sorwmis = SolventModule::sorwmis(elemCtx, scvIdx, timeIdx);
903 const auto& sgcwmis = SolventModule::sgcwmis(elemCtx, scvIdx, timeIdx);
904 const Evaluation zero = 0.0;
905 const Evaluation& sw = fs.saturation(waterPhaseIdx);
906 if (FluidSystem::phaseIsActive(oilPhaseIdx)) {
907 oilEffSat = std::max(oilEffSat - sorwmis.eval(sw,
true), zero);
909 gasEffSat = std::max(gasEffSat - sgcwmis.eval(sw,
true), zero);
910 solventEffSat = std::max(solventEffSat - sgcwmis.eval(sw,
true), zero);
912 const Evaluation oilGasSolventEffSat = oilEffSat + gasEffSat + solventEffSat;
913 const Evaluation oilSolventEffSat = oilEffSat + solventEffSat;
914 const Evaluation solventGasEffSat = solventEffSat + gasEffSat;
921 const Evaluation& p =
922 FluidSystem::phaseIsActive(oilPhaseIdx)
923 ? fs.pressure(oilPhaseIdx)
924 : fs.pressure(gasPhaseIdx);
926 const auto& pmiscTable = SolventModule::pmisc(elemCtx, scvIdx, timeIdx);
927 const Evaluation pmisc = pmiscTable.eval(p,
true);
928 const auto& tlPMixTable = SolventModule::tlPMixTable(elemCtx, scvIdx, timeIdx);
929 const Evaluation tlMixParamMu = SolventModule::tlMixParamViscosity(elemCtx, scvIdx, timeIdx) *
930 tlPMixTable.eval(p,
true);
932 const Evaluation& muGas = fs.viscosity(gasPhaseIdx);
933 const Evaluation& muSolvent = solventViscosity_;
935 assert(muGas.value() > 0);
936 assert(muSolvent.value() > 0);
937 const Evaluation muGasPow = pow(muGas, 0.25);
938 const Evaluation muSolventPow = pow(muSolvent, 0.25);
940 Evaluation muMixSolventGas = muGas;
941 if (solventGasEffSat > cutOff) {
942 muMixSolventGas *= muSolvent / pow(((gasEffSat / solventGasEffSat) * muSolventPow) +
943 ((solventEffSat / solventGasEffSat) * muGasPow), 4.0);
946 Evaluation muOil = 1.0;
947 Evaluation muOilPow = 1.0;
948 Evaluation muMixOilSolvent = 1.0;
949 Evaluation muOilEff = 1.0;
950 if (FluidSystem::phaseIsActive(oilPhaseIdx)) {
951 muOil = fs.viscosity(oilPhaseIdx);
952 assert(muOil.value() > 0);
953 muOilPow = pow(muOil, 0.25);
954 muMixOilSolvent = muOil;
955 if (oilSolventEffSat > cutOff) {
956 muMixOilSolvent *= muSolvent / pow(((oilEffSat / oilSolventEffSat) * muSolventPow) +
957 ((solventEffSat / oilSolventEffSat) * muOilPow), 4.0);
960 muOilEff = pow(muOil,1.0 - tlMixParamMu) * pow(muMixOilSolvent, tlMixParamMu);
962 Evaluation muMixSolventGasOil = muOil;
963 if (oilGasSolventEffSat > cutOff) {
964 muMixSolventGasOil *= muSolvent * muGas / pow(((oilEffSat / oilGasSolventEffSat) *
965 muSolventPow * muGasPow) +
966 ((solventEffSat / oilGasSolventEffSat) *
967 muOilPow * muGasPow) +
968 ((gasEffSat / oilGasSolventEffSat) *
969 muSolventPow * muOilPow), 4.0);
972 Evaluation muGasEff = pow(muGas,1.0 - tlMixParamMu) * pow(muMixSolventGas, tlMixParamMu);
973 const Evaluation muSolventEff = pow(muSolvent,1.0 - tlMixParamMu) * pow(muMixSolventGasOil, tlMixParamMu);
976 const Evaluation& rhoGas = fs.density(gasPhaseIdx);
977 Evaluation rhoOil = 0.0;
978 if (FluidSystem::phaseIsActive(oilPhaseIdx)) {
979 rhoOil = fs.density(oilPhaseIdx);
982 Evaluation rhoSolvent = solventDensity();
988 const Evaluation tlMixParamRho = SolventModule::tlMixParamDensity(elemCtx, scvIdx, timeIdx) *
989 tlPMixTable.eval(p,
true);
993 const Evaluation muOilEffPow = pow(pow(muOil, 1.0 - tlMixParamRho) *
994 pow(muMixOilSolvent, tlMixParamRho), 0.25);
995 const Evaluation muGasEffPow = pow(pow(muGas, 1.0 - tlMixParamRho) *
996 pow(muMixSolventGas, tlMixParamRho), 0.25);
997 const Evaluation muSolventEffPow = pow(pow(muSolvent, 1.0 - tlMixParamRho) *
998 pow(muMixSolventGasOil, tlMixParamRho), 0.25);
1000 const Evaluation oilGasEffSaturation = oilEffSat + gasEffSat;
1001 Evaluation sof = 0.0;
1002 Evaluation sgf = 0.0;
1003 if (oilGasEffSaturation.value() > cutOff) {
1004 sof = oilEffSat / oilGasEffSaturation;
1005 sgf = gasEffSat / oilGasEffSaturation;
1008 const Evaluation muSolventOilGasPow = muSolventPow * ((sgf * muOilPow) + (sof * muGasPow));
1010 Evaluation rhoMixSolventGasOil = 0.0;
1011 if (oilGasSolventEffSat.value() > cutOff) {
1012 rhoMixSolventGasOil = (rhoOil * oilEffSat / oilGasSolventEffSat) +
1013 (rhoGas * gasEffSat / oilGasSolventEffSat) +
1014 (rhoSolvent * solventEffSat / oilGasSolventEffSat);
1017 Evaluation rhoGasEff = 0.0;
1018 if (std::abs(muSolventPow.value() - muGasPow.value()) < cutOff) {
1019 rhoGasEff = ((1.0 - tlMixParamRho) * rhoGas) +
1020 (tlMixParamRho * rhoMixSolventGasOil);
1023 const Evaluation solventGasEffFraction = (muGasPow * (muSolventPow - muGasEffPow)) /
1024 (muGasEffPow * (muSolventPow - muGasPow));
1025 rhoGasEff = (rhoGas * solventGasEffFraction) + (rhoSolvent * (1.0 - solventGasEffFraction));
1028 Evaluation rhoSolventEff = 0.0;
1029 if (std::abs((muSolventOilGasPow.value() - (muOilPow.value() * muGasPow.value()))) < cutOff) {
1030 rhoSolventEff = ((1.0 - tlMixParamRho) * rhoSolvent) + (tlMixParamRho * rhoMixSolventGasOil);
1033 const Evaluation sfraction_se = (muSolventOilGasPow -
1034 muOilPow * muGasPow * muSolventPow / muSolventEffPow) /
1035 (muSolventOilGasPow - (muOilPow * muGasPow));
1036 rhoSolventEff = (rhoSolvent * sfraction_se) +
1037 (rhoGas * sgf * (1.0 - sfraction_se)) +
1038 (rhoOil * sof * (1.0 - sfraction_se));
1042 const unsigned pvtRegionIdx = asImp_().pvtRegionIndex();
1043 Evaluation bGasEff = rhoGasEff;
1044 if (FluidSystem::phaseIsActive(oilPhaseIdx)) {
1045 bGasEff /= (FluidSystem::referenceDensity(gasPhaseIdx, pvtRegionIdx) +
1046 FluidSystem::referenceDensity(oilPhaseIdx, pvtRegionIdx) * fs.Rv());
1048 bGasEff /= (FluidSystem::referenceDensity(gasPhaseIdx, pvtRegionIdx));
1050 const Evaluation bSolventEff = rhoSolventEff / solventRefDensity();
1053 const Evaluation bg = fs.invB(gasPhaseIdx);
1054 const Evaluation bs = solventInverseFormationVolumeFactor();
1055 const Evaluation bg_eff = pmisc * bGasEff + (1.0 - pmisc) * bg;
1056 const Evaluation bs_eff = pmisc * bSolventEff + (1.0 - pmisc) * bs;
1059 if (FluidSystem::phaseIsActive(oilPhaseIdx)) {
1060 fs.setDensity(gasPhaseIdx,
1062 (FluidSystem::referenceDensity(gasPhaseIdx, pvtRegionIdx) +
1063 FluidSystem::referenceDensity(oilPhaseIdx, pvtRegionIdx)*fs.Rv()));
1065 fs.setDensity(gasPhaseIdx,
1066 bg_eff * FluidSystem::referenceDensity(gasPhaseIdx, pvtRegionIdx));
1068 rhoSolvent = bs_eff * solventRefDensity();
1069 fs.setSolventDensity(rhoSolvent);
1072 Evaluation& mobg = asImp_().mobility_[gasPhaseIdx];
1073 muGasEff = bg_eff / (pmisc * bGasEff / muGasEff + (1.0 - pmisc) * bg / muGas);
1074 mobg *= muGas / muGasEff;
1077 solventViscosity_ = bs_eff / (pmisc * bSolventEff / muSolventEff +
1078 (1.0 - pmisc) * bs / muSolvent);
1080 if (FluidSystem::phaseIsActive(oilPhaseIdx)) {
1081 Evaluation rhoOilEff = 0.0;
1082 if (std::abs(muOilPow.value() - muSolventPow.value()) < cutOff) {
1083 rhoOilEff = ((1.0 - tlMixParamRho) * rhoOil) + (tlMixParamRho * rhoMixSolventGasOil);
1086 const Evaluation solventOilEffFraction = (muOilPow * (muOilEffPow - muSolventPow)) /
1087 (muOilEffPow * (muOilPow - muSolventPow));
1088 rhoOilEff = (rhoOil * solventOilEffFraction) + (rhoSolvent * (1.0 - solventOilEffFraction));
1090 const Evaluation bOilEff =
1091 rhoOilEff / (FluidSystem::referenceDensity(oilPhaseIdx, pvtRegionIdx) +
1092 FluidSystem::referenceDensity(gasPhaseIdx, pvtRegionIdx) * fs.Rs());
1093 const Evaluation bo = fs.invB(oilPhaseIdx);
1094 const Evaluation bo_eff = pmisc * bOilEff + (1.0 - pmisc) * bo;
1095 fs.setDensity(oilPhaseIdx,
1096 bo_eff * (FluidSystem::referenceDensity(oilPhaseIdx, pvtRegionIdx) +
1097 FluidSystem::referenceDensity(gasPhaseIdx, pvtRegionIdx) * fs.Rs()));
1100 Evaluation& mobo = asImp_().mobility_[oilPhaseIdx];
1101 muOilEff = bo_eff / (pmisc * bOilEff / muOilEff + (1.0 - pmisc) * bo / muOil);
1102 mobo *= muOil / muOilEff;
1107 Implementation& asImp_()
1108 {
return *
static_cast<Implementation*
>(
this); }
1110 const Implementation& asImp_()
const 1111 {
return *
static_cast<const Implementation*
>(
this); }
1113 Evaluation hydrocarbonSaturation_;
1114 Evaluation solventViscosity_;
1115 Evaluation solventMobility_;
1117 Scalar solventRefDensity_;
1127 template <
class TypeTag>
1140 using Toolbox = MathToolbox<Evaluation>;
1142 static constexpr
unsigned gasPhaseIdx = FluidSystem::gasPhaseIdx;
1143 static constexpr
int dimWorld = GridView::dimensionworld;
1145 using DimVector = Dune::FieldVector<Scalar, dimWorld>;
1146 using DimEvalVector = Dune::FieldVector<Evaluation, dimWorld>;
1153 template <
class Dummy =
bool>
1159 const auto& gradCalc = elemCtx.gradientCalculator();
1162 const auto& scvf = elemCtx.stencil(timeIdx).interiorFace(scvfIdx);
1163 const auto& faceNormal = scvf.normal();
1165 const unsigned i = scvf.interiorIndex();
1166 const unsigned j = scvf.exteriorIndex();
1169 DimEvalVector solventPGrad;
1171 gradCalc.calculateGradient(solventPGrad,
1175 Valgrind::CheckDefined(solventPGrad);
1178 if (Parameters::Get<Parameters::EnableGravity>()) {
1181 const auto& gIn = elemCtx.problem().gravity(elemCtx, i, timeIdx);
1182 const auto& gEx = elemCtx.problem().gravity(elemCtx, j, timeIdx);
1184 const auto& intQuantsIn = elemCtx.intensiveQuantities(i, timeIdx);
1185 const auto& intQuantsEx = elemCtx.intensiveQuantities(j, timeIdx);
1187 const auto& posIn = elemCtx.pos(i, timeIdx);
1188 const auto& posEx = elemCtx.pos(j, timeIdx);
1189 const auto& posFace = scvf.integrationPos();
1192 DimVector distVecIn(posIn);
1193 DimVector distVecEx(posEx);
1194 DimVector distVecTotal(posEx);
1196 distVecIn -= posFace;
1197 distVecEx -= posFace;
1198 distVecTotal -= posIn;
1199 const Scalar absDistTotalSquared = distVecTotal.two_norm2();
1202 auto rhoIn = intQuantsIn.solventDensity();
1203 auto pStatIn = - rhoIn * (gIn * distVecIn);
1207 Scalar rhoEx = Toolbox::value(intQuantsEx.solventDensity());
1208 Scalar pStatEx = - rhoEx * (gEx * distVecEx);
1214 DimEvalVector f(distVecTotal);
1215 f *= (pStatEx - pStatIn) / absDistTotalSquared;
1218 for (
unsigned dimIdx = 0; dimIdx < dimWorld; ++dimIdx) {
1219 solventPGrad[dimIdx] += f[dimIdx];
1221 if (!isfinite(solventPGrad[dimIdx])) {
1222 throw NumericalProblem(
"Non-finite potential gradient for solvent 'phase'");
1228 Evaluation solventPGradNormal = 0.0;
1229 for (
unsigned dimIdx = 0; dimIdx < faceNormal.size(); ++dimIdx) {
1230 solventPGradNormal += solventPGrad[dimIdx]*faceNormal[dimIdx];
1233 if (solventPGradNormal > 0) {
1234 solventUpstreamDofIdx_ = j;
1235 solventDownstreamDofIdx_ = i;
1238 solventUpstreamDofIdx_ = i;
1239 solventDownstreamDofIdx_ = j;
1242 const auto& up = elemCtx.intensiveQuantities(solventUpstreamDofIdx_, timeIdx);
1248 if (solventUpstreamDofIdx_ == i) {
1249 solventVolumeFlux_ = solventPGradNormal * up.solventMobility();
1252 solventVolumeFlux_ = solventPGradNormal * scalarValue(up.solventMobility());
1260 template <
class Dummy =
bool>
1266 const ExtensiveQuantities& extQuants = asImp_();
1268 const unsigned interiorDofIdx = extQuants.interiorIndex();
1269 const unsigned exteriorDofIdx = extQuants.exteriorIndex();
1270 assert(interiorDofIdx != exteriorDofIdx);
1272 const auto& intQuantsIn = elemCtx.intensiveQuantities(interiorDofIdx, timeIdx);
1273 const auto& intQuantsEx = elemCtx.intensiveQuantities(exteriorDofIdx, timeIdx);
1275 const unsigned I = elemCtx.globalSpaceIndex(interiorDofIdx, timeIdx);
1276 const unsigned J = elemCtx.globalSpaceIndex(exteriorDofIdx, timeIdx);
1278 const Scalar thpresInToEx = elemCtx.problem().thresholdPressure(I, J);
1279 const Scalar thpresExToIn = elemCtx.problem().thresholdPressure(J, I);
1280 const Scalar trans = elemCtx.problem().transmissibility(elemCtx, interiorDofIdx, exteriorDofIdx);
1281 const Scalar g = elemCtx.problem().gravity()[dimWorld - 1];
1283 const Scalar zIn = elemCtx.problem().dofCenterDepth(elemCtx, interiorDofIdx, timeIdx);
1284 const Scalar zEx = elemCtx.problem().dofCenterDepth(elemCtx, exteriorDofIdx, timeIdx);
1285 const Scalar distZ = zIn - zEx;
1287 const Evaluation rhoIn = intQuantsIn.solventDensity();
1288 const Scalar rhoEx = Toolbox::value(intQuantsEx.solventDensity());
1289 const Evaluation rhoAvg = rhoIn * 0.5 + rhoEx * 0.5;
1291 const Evaluation& pressureInterior = intQuantsIn.fluidState().pressure(gasPhaseIdx);
1292 Evaluation pressureExterior = Toolbox::value(intQuantsEx.fluidState().pressure(gasPhaseIdx));
1293 pressureExterior += distZ * g * rhoAvg;
1295 Evaluation pressureDiffSolvent = pressureExterior - pressureInterior;
1296 const Scalar thpres = pressureDiffSolvent < 0.0 ? thpresInToEx : thpresExToIn;
1298 if (std::abs(scalarValue(pressureDiffSolvent)) > thpres) {
1299 if (pressureDiffSolvent < 0.0) {
1300 pressureDiffSolvent += thpres;
1303 pressureDiffSolvent -= thpres;
1307 pressureDiffSolvent = 0.0;
1311 if (pressureDiffSolvent > 0.0) {
1312 solventUpstreamDofIdx_ = exteriorDofIdx;
1313 solventDownstreamDofIdx_ = interiorDofIdx;
1315 else if (pressureDiffSolvent < 0.0) {
1316 solventUpstreamDofIdx_ = interiorDofIdx;
1317 solventDownstreamDofIdx_ = exteriorDofIdx;
1323 solventUpstreamDofIdx_ = std::min(interiorDofIdx, exteriorDofIdx);
1324 solventDownstreamDofIdx_ = std::max(interiorDofIdx, exteriorDofIdx);
1325 solventVolumeFlux_ = 0.0;
1329 const Scalar faceArea = elemCtx.stencil(timeIdx).interiorFace(scvfIdx).area();
1330 const IntensiveQuantities& up = elemCtx.intensiveQuantities(solventUpstreamDofIdx_, timeIdx);
1331 if (solventUpstreamDofIdx_ == interiorDofIdx) {
1332 solventVolumeFlux_ = up.solventMobility() * (-trans / faceArea) * pressureDiffSolvent;
1335 solventVolumeFlux_ =
1336 scalarValue(up.solventMobility()) * (-trans / faceArea) * pressureDiffSolvent;
1340 unsigned solventUpstreamIndex()
const 1341 {
return solventUpstreamDofIdx_; }
1343 unsigned solventDownstreamIndex()
const 1344 {
return solventDownstreamDofIdx_; }
1346 const Evaluation& solventVolumeFlux()
const 1347 {
return solventVolumeFlux_; }
1349 void setSolventVolumeFlux(
const Evaluation& solventVolumeFlux)
1350 { solventVolumeFlux_ = solventVolumeFlux; }
1353 Implementation& asImp_()
1354 {
return *
static_cast<Implementation*
>(
this); }
1356 Evaluation solventVolumeFlux_;
1357 unsigned solventUpstreamDofIdx_;
1358 unsigned solventDownstreamDofIdx_;
static void assignPrimaryVars(PrimaryVariables &priVars, Scalar solventSaturation, Scalar solventRsw)
Assign the solvent specific primary variables to a PrimaryVariables object.
Definition: blackoilsolventmodules.hh:270
Provides the solvent specific extensive quantities to the generic black-oil module's extensive quanti...
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
static void registerParameters()
Register all run-time parameters for the black-oil solvent module.
Definition: blackoilsolventmodules.hh:116
VTK output module for the black oil model's solvent related quantities.
static void registerOutputModules(Model &model, Simulator &simulator)
Register all solvent specific VTK and ECL output modules.
Definition: blackoilsolventmodules.hh:124
Structs needed for tpfalinearizer and its gpuparams struct extracted to be defined in one place that ...
Definition: blackoilbioeffectsmodules.hh:45
Contains classes extending the black-oil model.
static void setSolventPvt(const SolventPvt &value)
Specify the solvent PVT of a all PVT regions.
Definition: blackoilsolventmodules.hh:107
Declares the properties required by the black oil model.
Contains the parameters required to extend the black-oil model by solvents.
VTK output module for the black oil model's solvent related quantities.
Definition: vtkblackoilsolventmodule.hpp:53
Definition: linearizationtype.hh:33
This method contains all callback classes for quantities that are required by some extensive quantiti...
void updateVolumeFluxTrans(const ElementContext &elemCtx, unsigned scvfIdx, unsigned timeIdx)
Method which calculates the volume flux of the polymer "phase" using the gas pressure potential diffe...
Definition: blackoilsolventmodules.hh:1262
The common code for the linearizers of non-linear systems of equations.
static void updatePrimaryVars(PrimaryVariables &newPv, const PrimaryVariables &oldPv, const EqVector &delta)
Do a Newton-Raphson update the primary variables of the solvents.
Definition: blackoilsolventmodules.hh:287
Contains the high level supplements required to extend the black oil model by solvents.
Definition: blackoilsolventmodules.hh:68
void solventPvtUpdate_(const ElementContext &elemCtx, unsigned scvIdx, unsigned timeIdx)
Update the intensive PVT properties needed to handle solvents from the primary variables.
Definition: blackoilsolventmodules.hh:784
Callback class for a phase pressure.
Definition: quantitycallbacks.hh:84
Struct holding the parameters for the BlackOilSolventModule class.
Definition: blackoilsolventparams.hpp:46
void solventPostSatFuncUpdate_(const ElementContext &elemCtx, unsigned dofIdx, unsigned timeIdx)
Called after the saturation functions have been doing their magic.
Definition: blackoilsolventmodules.hh:601
static void setParams(BlackOilSolventParams< Scalar > &¶ms)
Set parameters.
Definition: blackoilsolventmodules.hh:101
Provides the volumetric quantities required for the equations needed by the solvents extension of the...
static Scalar computeResidualError(const EqVector &resid)
Return how much a residual is considered an error.
Definition: blackoilsolventmodules.hh:310
void updateVolumeFluxPerm(const ElementContext &elemCtx, unsigned scvfIdx, unsigned timeIdx)
Method which calculates the volume flux of the polymer "phase" using the pressure potential gradient ...
Definition: blackoilsolventmodules.hh:1155
static Scalar computeUpdateError(const PrimaryVariables &, const EqVector &)
Return how much a Newton-Raphson update is considered an error.
Definition: blackoilsolventmodules.hh:298
static void registerParameters()
Register all run-time parameters for the multi-phase VTK output module.
Definition: vtkblackoilsolventmodule.hpp:84
void solventPreSatFuncUpdate_(const ElementContext &elemCtx, unsigned dofIdx, unsigned timeIdx)
Called before the saturation functions are doing their magic.
Definition: blackoilsolventmodules.hh:562
Defines the common parameters for the porous medium multi-phase models.
void setPhaseIndex(unsigned phaseIdx)
Set the index of the fluid phase for which the pressure should be returned.
Definition: quantitycallbacks.hh:109