77 using Toolbox = MathToolbox<Evaluation>;
79 static constexpr unsigned zFractionIdx = Indices::zFractionIdx;
80 static constexpr unsigned contiZfracEqIdx = Indices::contiZfracEqIdx;
81 static constexpr unsigned enableExtbo = enableExtboV;
83 static constexpr unsigned gasPhaseIdx = FluidSystem::gasPhaseIdx;
84 static constexpr unsigned oilPhaseIdx = FluidSystem::oilPhaseIdx;
107 static bool primaryVarApplies(
unsigned pvIdx)
109 if constexpr (enableExtbo) {
110 return pvIdx == zFractionIdx;
117 static std::string primaryVarName([[maybe_unused]]
unsigned pvIdx)
119 assert(primaryVarApplies(pvIdx));
124 static Scalar primaryVarWeight([[maybe_unused]]
unsigned pvIdx)
126 assert(primaryVarApplies(pvIdx));
129 return static_cast<Scalar
>(1.0);
132 static bool eqApplies(
unsigned eqIdx)
134 if constexpr (enableExtbo) {
135 return eqIdx == contiZfracEqIdx;
142 static std::string eqName([[maybe_unused]]
unsigned eqIdx)
144 assert(eqApplies(eqIdx));
146 return "conti^solvent";
149 static Scalar eqWeight([[maybe_unused]]
unsigned eqIdx)
151 assert(eqApplies(eqIdx));
154 return static_cast<Scalar
>(1.0);
157 template <
class StorageType>
158 OPM_HOST_DEVICE
static void addStorage(StorageType& storage,
159 const IntensiveQuantities& intQuants)
161 using LhsEval =
typename StorageType::value_type;
163 if constexpr (enableExtbo) {
164 if constexpr (blackoilConserveSurfaceVolume) {
165 storage[contiZfracEqIdx] =
166 Toolbox::template decay<LhsEval>(intQuants.porosity()) *
167 Toolbox::template decay<LhsEval>(intQuants.yVolume()) *
168 Toolbox::template decay<LhsEval>(intQuants.fluidState().saturation(gasPhaseIdx)) *
169 Toolbox::template decay<LhsEval>(intQuants.fluidState().invB(gasPhaseIdx));
170 if (FluidSystem::enableDissolvedGas()) {
171 storage[contiZfracEqIdx] +=
172 Toolbox::template decay<LhsEval>(intQuants.porosity()) *
173 Toolbox::template decay<LhsEval>(intQuants.xVolume()) *
174 Toolbox::template decay<LhsEval>(intQuants.fluidState().Rs()) *
175 Toolbox::template decay<LhsEval>(intQuants.fluidState().saturation(oilPhaseIdx)) *
176 Toolbox::template decay<LhsEval>(intQuants.fluidState().invB(oilPhaseIdx));
181 const Scalar regWghtFactor = 1.0e-6;
182 storage[contiZfracEqIdx] +=
183 regWghtFactor* (1.0 - Toolbox::template decay<LhsEval>(intQuants.zFraction())) +
184 regWghtFactor*Toolbox::template decay<LhsEval>(intQuants.porosity()) *
185 Toolbox::template decay<LhsEval>(intQuants.fluidState().saturation(gasPhaseIdx)) *
186 Toolbox::template decay<LhsEval>(intQuants.fluidState().invB(gasPhaseIdx));
187 storage[contiZfracEqIdx - 1] += regWghtFactor*Toolbox::template decay<LhsEval>(intQuants.zFraction());
190 throw std::runtime_error(
"Only component conservation in terms of surface volumes is implemented. ");
195 static void computeFlux([[maybe_unused]] RateVector& flux,
196 [[maybe_unused]]
const ElementContext& elemCtx,
197 [[maybe_unused]]
unsigned scvfIdx,
198 [[maybe_unused]]
unsigned timeIdx)
200 if constexpr (enableExtbo) {
201 const auto& extQuants = elemCtx.extensiveQuantities(scvfIdx, timeIdx);
203 if constexpr (blackoilConserveSurfaceVolume) {
204 const unsigned inIdx = extQuants.interiorIndex();
206 const unsigned upIdxGas =
static_cast<unsigned>(extQuants.upstreamIndex(gasPhaseIdx));
207 const auto& upGas = elemCtx.intensiveQuantities(upIdxGas, timeIdx);
208 const auto& fsGas = upGas.fluidState();
209 if (upIdxGas == inIdx) {
210 flux[contiZfracEqIdx] =
211 extQuants.volumeFlux(gasPhaseIdx) *
213 fsGas.invB(gasPhaseIdx);
216 flux[contiZfracEqIdx] =
217 extQuants.volumeFlux(gasPhaseIdx) *
218 decay<Scalar>(upGas.yVolume()) *
219 decay<Scalar>(fsGas.invB(gasPhaseIdx));
221 if (FluidSystem::enableDissolvedGas()) {
222 const unsigned upIdxOil =
static_cast<unsigned>(extQuants.upstreamIndex(oilPhaseIdx));
223 const auto& upOil = elemCtx.intensiveQuantities(upIdxOil, timeIdx);
224 const auto& fsOil = upOil.fluidState();
225 if (upIdxOil == inIdx) {
226 flux[contiZfracEqIdx] +=
227 extQuants.volumeFlux(oilPhaseIdx) *
230 fsOil.invB(oilPhaseIdx);
233 flux[contiZfracEqIdx] +=
234 extQuants.volumeFlux(oilPhaseIdx) *
235 decay<Scalar>(upOil.xVolume()) *
236 decay<Scalar>(fsOil.Rs()) *
237 decay<Scalar>(fsOil.invB(oilPhaseIdx));
242 throw std::runtime_error(
"Only component conservation in terms of surface volumes is implemented. ");
253 if constexpr (enableExtbo) {
254 priVars[zFractionIdx] = zFraction;
262 const PrimaryVariables& oldPv,
263 const EqVector& delta)
265 if constexpr (enableExtbo) {
267 newPv[zFractionIdx] = oldPv[zFractionIdx] - delta[zFractionIdx];
280 return static_cast<Scalar
>(0.0);
289 return std::abs(Toolbox::scalarValue(resid[contiZfracEqIdx]));
292 template <
class DofEntity>
293 static void serializeEntity(
const Model& model, std::ostream& outstream,
const DofEntity& dof)
295 if constexpr (enableExtbo) {
296 const unsigned dofIdx = model.dofMapper().index(dof);
298 const PrimaryVariables& priVars = model.solution(0)[dofIdx];
299 outstream << priVars[zFractionIdx];
303 template <
class DofEntity>
304 static void deserializeEntity(Model& model, std::istream& instream,
const DofEntity& dof)
306 if constexpr (enableExtbo) {
307 const unsigned dofIdx = model.dofMapper().index(dof);
309 PrimaryVariables& priVars0 = model.solution(0)[dofIdx];
310 PrimaryVariables& priVars1 = model.solution(1)[dofIdx];
312 instream >> priVars0[zFractionIdx];
315 priVars1 = priVars0[zFractionIdx];
319 template <
typename Value>
320 static Value xVolume(
unsigned pvtRegionIdx,
const Value& pressure,
const Value& z)
321 {
return params_.X_[pvtRegionIdx].eval(z, pressure,
true); }
323 template <
typename Value>
324 static Value yVolume(
unsigned pvtRegionIdx,
const Value& pressure,
const Value& z)
325 {
return params_.Y_[pvtRegionIdx].eval(z, pressure,
true); }
327 template <
typename Value>
328 static Value pbubRs(
unsigned pvtRegionIdx,
const Value& z,
const Value& rs)
329 {
return params_.PBUB_RS_[pvtRegionIdx].eval(z, rs,
true); }
331 template <
typename Value>
332 static Value pbubRv(
unsigned pvtRegionIdx,
const Value& z,
const Value& rv)
333 {
return params_.PBUB_RV_[pvtRegionIdx].eval(z, rv,
true); }
335 template <
typename Value>
336 static Value oilViscosity(
unsigned pvtRegionIdx,
const Value& pressure,
const Value& z)
337 {
return params_.VISCO_[pvtRegionIdx].eval(z, pressure,
true); }
339 template <
typename Value>
340 static Value gasViscosity(
unsigned pvtRegionIdx,
const Value& pressure,
const Value& z)
341 {
return params_.VISCG_[pvtRegionIdx].eval(z, pressure,
true); }
343 template <
typename Value>
344 static Value bo(
unsigned pvtRegionIdx,
const Value& pressure,
const Value& z)
345 {
return params_.BO_[pvtRegionIdx].eval(z, pressure,
true); }
347 template <
typename Value>
348 static Value bg(
unsigned pvtRegionIdx,
const Value& pressure,
const Value& z)
349 {
return params_.BG_[pvtRegionIdx].eval(z, pressure,
true); }
351 template <
typename Value>
352 static Value rs(
unsigned pvtRegionIdx,
const Value& pressure,
const Value& z)
353 {
return params_.RS_[pvtRegionIdx].eval(z, pressure,
true); }
355 template <
typename Value>
356 static Value rv(
unsigned pvtRegionIdx,
const Value& pressure,
const Value& z)
357 {
return params_.RV_[pvtRegionIdx].eval(z, pressure,
true); }
359 static Scalar referenceDensity(
unsigned regionIdx)
360 {
return params_.zReferenceDensity_[regionIdx]; }
362 static Scalar zLim(
unsigned regionIdx)
363 {
return params_.zLim_[regionIdx]; }
365 template <
typename Value>
366 static Value oilCmp(
unsigned pvtRegionIdx,
const Value& z)
367 {
return params_.oilCmp_[pvtRegionIdx].eval(z,
true); }
369 template <
typename Value>
370 static Value gasCmp(
unsigned pvtRegionIdx,
const Value& z)
371 {
return params_.gasCmp_[pvtRegionIdx].eval(z,
true); }
374 static BlackOilExtboParams<Scalar> params_;