75 using Toolbox = MathToolbox<Evaluation>;
77 static constexpr unsigned zFractionIdx = Indices::zFractionIdx;
78 static constexpr unsigned contiZfracEqIdx = Indices::contiZfracEqIdx;
79 static constexpr unsigned enableExtbo = enableExtboV;
81 static constexpr unsigned gasPhaseIdx = FluidSystem::gasPhaseIdx;
82 static constexpr unsigned oilPhaseIdx = FluidSystem::oilPhaseIdx;
105 static bool primaryVarApplies(
unsigned pvIdx)
107 if constexpr (enableExtbo) {
108 return pvIdx == zFractionIdx;
115 static std::string primaryVarName([[maybe_unused]]
unsigned pvIdx)
117 assert(primaryVarApplies(pvIdx));
122 static Scalar primaryVarWeight([[maybe_unused]]
unsigned pvIdx)
124 assert(primaryVarApplies(pvIdx));
127 return static_cast<Scalar
>(1.0);
130 static bool eqApplies(
unsigned eqIdx)
132 if constexpr (enableExtbo) {
133 return eqIdx == contiZfracEqIdx;
140 static std::string eqName([[maybe_unused]]
unsigned eqIdx)
142 assert(eqApplies(eqIdx));
144 return "conti^solvent";
147 static Scalar eqWeight([[maybe_unused]]
unsigned eqIdx)
149 assert(eqApplies(eqIdx));
152 return static_cast<Scalar
>(1.0);
155 template <
class LhsEval>
156 static void addStorage(Dune::FieldVector<LhsEval, numEq>& storage,
157 const IntensiveQuantities& intQuants)
159 if constexpr (enableExtbo) {
160 if constexpr (blackoilConserveSurfaceVolume) {
161 storage[contiZfracEqIdx] =
162 Toolbox::template decay<LhsEval>(intQuants.porosity()) *
163 Toolbox::template decay<LhsEval>(intQuants.yVolume()) *
164 Toolbox::template decay<LhsEval>(intQuants.fluidState().saturation(gasPhaseIdx)) *
165 Toolbox::template decay<LhsEval>(intQuants.fluidState().invB(gasPhaseIdx));
166 if (FluidSystem::enableDissolvedGas()) {
167 storage[contiZfracEqIdx] +=
168 Toolbox::template decay<LhsEval>(intQuants.porosity()) *
169 Toolbox::template decay<LhsEval>(intQuants.xVolume()) *
170 Toolbox::template decay<LhsEval>(intQuants.fluidState().Rs()) *
171 Toolbox::template decay<LhsEval>(intQuants.fluidState().saturation(oilPhaseIdx)) *
172 Toolbox::template decay<LhsEval>(intQuants.fluidState().invB(oilPhaseIdx));
177 const Scalar regWghtFactor = 1.0e-6;
178 storage[contiZfracEqIdx] +=
179 regWghtFactor* (1.0 - Toolbox::template decay<LhsEval>(intQuants.zFraction())) +
180 regWghtFactor*Toolbox::template decay<LhsEval>(intQuants.porosity()) *
181 Toolbox::template decay<LhsEval>(intQuants.fluidState().saturation(gasPhaseIdx)) *
182 Toolbox::template decay<LhsEval>(intQuants.fluidState().invB(gasPhaseIdx));
183 storage[contiZfracEqIdx - 1] += regWghtFactor*Toolbox::template decay<LhsEval>(intQuants.zFraction());
186 throw std::runtime_error(
"Only component conservation in terms of surface volumes is implemented. ");
191 static void computeFlux([[maybe_unused]] RateVector& flux,
192 [[maybe_unused]]
const ElementContext& elemCtx,
193 [[maybe_unused]]
unsigned scvfIdx,
194 [[maybe_unused]]
unsigned timeIdx)
196 if constexpr (enableExtbo) {
197 const auto& extQuants = elemCtx.extensiveQuantities(scvfIdx, timeIdx);
199 if constexpr (blackoilConserveSurfaceVolume) {
200 const unsigned inIdx = extQuants.interiorIndex();
202 const unsigned upIdxGas =
static_cast<unsigned>(extQuants.upstreamIndex(gasPhaseIdx));
203 const auto& upGas = elemCtx.intensiveQuantities(upIdxGas, timeIdx);
204 const auto& fsGas = upGas.fluidState();
205 if (upIdxGas == inIdx) {
206 flux[contiZfracEqIdx] =
207 extQuants.volumeFlux(gasPhaseIdx) *
209 fsGas.invB(gasPhaseIdx);
212 flux[contiZfracEqIdx] =
213 extQuants.volumeFlux(gasPhaseIdx) *
214 decay<Scalar>(upGas.yVolume()) *
215 decay<Scalar>(fsGas.invB(gasPhaseIdx));
217 if (FluidSystem::enableDissolvedGas()) {
218 const unsigned upIdxOil =
static_cast<unsigned>(extQuants.upstreamIndex(oilPhaseIdx));
219 const auto& upOil = elemCtx.intensiveQuantities(upIdxOil, timeIdx);
220 const auto& fsOil = upOil.fluidState();
221 if (upIdxOil == inIdx) {
222 flux[contiZfracEqIdx] +=
223 extQuants.volumeFlux(oilPhaseIdx) *
226 fsOil.invB(oilPhaseIdx);
229 flux[contiZfracEqIdx] +=
230 extQuants.volumeFlux(oilPhaseIdx) *
231 decay<Scalar>(upOil.xVolume()) *
232 decay<Scalar>(fsOil.Rs()) *
233 decay<Scalar>(fsOil.invB(oilPhaseIdx));
238 throw std::runtime_error(
"Only component conservation in terms of surface volumes is implemented. ");
249 if constexpr (enableExtbo) {
250 priVars[zFractionIdx] = zFraction;
258 const PrimaryVariables& oldPv,
259 const EqVector& delta)
261 if constexpr (enableExtbo) {
263 newPv[zFractionIdx] = oldPv[zFractionIdx] - delta[zFractionIdx];
276 return static_cast<Scalar
>(0.0);
285 return std::abs(Toolbox::scalarValue(resid[contiZfracEqIdx]));
288 template <
class DofEntity>
289 static void serializeEntity(
const Model& model, std::ostream& outstream,
const DofEntity& dof)
291 if constexpr (enableExtbo) {
292 const unsigned dofIdx = model.dofMapper().index(dof);
294 const PrimaryVariables& priVars = model.solution(0)[dofIdx];
295 outstream << priVars[zFractionIdx];
299 template <
class DofEntity>
300 static void deserializeEntity(Model& model, std::istream& instream,
const DofEntity& dof)
302 if constexpr (enableExtbo) {
303 const unsigned dofIdx = model.dofMapper().index(dof);
305 PrimaryVariables& priVars0 = model.solution(0)[dofIdx];
306 PrimaryVariables& priVars1 = model.solution(1)[dofIdx];
308 instream >> priVars0[zFractionIdx];
311 priVars1 = priVars0[zFractionIdx];
315 template <
typename Value>
316 static Value xVolume(
unsigned pvtRegionIdx,
const Value& pressure,
const Value& z)
317 {
return params_.X_[pvtRegionIdx].eval(z, pressure,
true); }
319 template <
typename Value>
320 static Value yVolume(
unsigned pvtRegionIdx,
const Value& pressure,
const Value& z)
321 {
return params_.Y_[pvtRegionIdx].eval(z, pressure,
true); }
323 template <
typename Value>
324 static Value pbubRs(
unsigned pvtRegionIdx,
const Value& z,
const Value& rs)
325 {
return params_.PBUB_RS_[pvtRegionIdx].eval(z, rs,
true); }
327 template <
typename Value>
328 static Value pbubRv(
unsigned pvtRegionIdx,
const Value& z,
const Value& rv)
329 {
return params_.PBUB_RV_[pvtRegionIdx].eval(z, rv,
true); }
331 template <
typename Value>
332 static Value oilViscosity(
unsigned pvtRegionIdx,
const Value& pressure,
const Value& z)
333 {
return params_.VISCO_[pvtRegionIdx].eval(z, pressure,
true); }
335 template <
typename Value>
336 static Value gasViscosity(
unsigned pvtRegionIdx,
const Value& pressure,
const Value& z)
337 {
return params_.VISCG_[pvtRegionIdx].eval(z, pressure,
true); }
339 template <
typename Value>
340 static Value bo(
unsigned pvtRegionIdx,
const Value& pressure,
const Value& z)
341 {
return params_.BO_[pvtRegionIdx].eval(z, pressure,
true); }
343 template <
typename Value>
344 static Value bg(
unsigned pvtRegionIdx,
const Value& pressure,
const Value& z)
345 {
return params_.BG_[pvtRegionIdx].eval(z, pressure,
true); }
347 template <
typename Value>
348 static Value rs(
unsigned pvtRegionIdx,
const Value& pressure,
const Value& z)
349 {
return params_.RS_[pvtRegionIdx].eval(z, pressure,
true); }
351 template <
typename Value>
352 static Value rv(
unsigned pvtRegionIdx,
const Value& pressure,
const Value& z)
353 {
return params_.RV_[pvtRegionIdx].eval(z, pressure,
true); }
355 static Scalar referenceDensity(
unsigned regionIdx)
356 {
return params_.zReferenceDensity_[regionIdx]; }
358 static Scalar zLim(
unsigned regionIdx)
359 {
return params_.zLim_[regionIdx]; }
361 template <
typename Value>
362 static Value oilCmp(
unsigned pvtRegionIdx,
const Value& z)
363 {
return params_.oilCmp_[pvtRegionIdx].eval(z,
true); }
365 template <
typename Value>
366 static Value gasCmp(
unsigned pvtRegionIdx,
const Value& z)
367 {
return params_.gasCmp_[pvtRegionIdx].eval(z,
true); }
370 static BlackOilExtboParams<Scalar> params_;