218 Valgrind::SetUndefined(*
this);
221 static_assert(std::is_same_v<Discretization, EcfvDiscretization<TypeTag>>);
223 const auto& stencil = elemCtx.stencil(timeIdx);
224 const auto& scvf = stencil.interiorFace(scvfIdx);
226 interiorDofIdx_ = scvf.interiorIndex();
227 exteriorDofIdx_ = scvf.exteriorIndex();
228 assert(interiorDofIdx_ != exteriorDofIdx_);
230 const unsigned I = stencil.globalSpaceIndex(interiorDofIdx_);
231 const unsigned J = stencil.globalSpaceIndex(exteriorDofIdx_);
233 const Scalar trans = transmissibility_(elemCtx, scvfIdx, timeIdx);
238 const Scalar g = elemCtx.problem().gravity()[dimWorld - 1];
240 const auto& intQuantsIn = elemCtx.intensiveQuantities(interiorDofIdx_, timeIdx);
241 const auto& intQuantsEx = elemCtx.intensiveQuantities(exteriorDofIdx_, timeIdx);
243 const Scalar zIn = dofCenterDepth_(elemCtx, interiorDofIdx_, timeIdx);
244 const Scalar zEx = dofCenterDepth_(elemCtx, exteriorDofIdx_, timeIdx);
247 const Scalar distZ = zIn - zEx;
249 for (
unsigned phaseIdx = 0; phaseIdx < numPhases; ++phaseIdx) {
250 if (!FluidSystem::phaseIsActive(phaseIdx)) {
256 if (intQuantsIn.mobility(phaseIdx) <= 0.0 &&
257 intQuantsEx.mobility(phaseIdx) <= 0.0)
259 upIdx_[phaseIdx] = interiorDofIdx_;
260 dnIdx_[phaseIdx] = exteriorDofIdx_;
261 pressureDifference_[phaseIdx] = 0.0;
262 volumeFlux_[phaseIdx] = 0.0;
268 const Evaluation& rhoIn = intQuantsIn.fluidState().density(phaseIdx);
269 const Scalar rhoEx = Toolbox::value(intQuantsEx.fluidState().density(phaseIdx));
270 const Evaluation rhoAvg = (rhoIn + rhoEx) / 2;
272 const Evaluation& pressureInterior = intQuantsIn.fluidState().pressure(phaseIdx);
273 Evaluation pressureExterior = Toolbox::value(intQuantsEx.fluidState().pressure(phaseIdx));
275 pressureExterior += rhoAvg * (distZ * g);
277 pressureDifference_[phaseIdx] = pressureExterior - pressureInterior;
283 if (pressureDifference_[phaseIdx] > 0.0) {
284 upIdx_[phaseIdx] = exteriorDofIdx_;
285 dnIdx_[phaseIdx] = interiorDofIdx_;
287 else if (pressureDifference_[phaseIdx] < 0.0) {
288 upIdx_[phaseIdx] = interiorDofIdx_;
289 dnIdx_[phaseIdx] = exteriorDofIdx_;
294 const Scalar Vin = elemCtx.dofVolume(interiorDofIdx_, 0);
295 const Scalar Vex = elemCtx.dofVolume(exteriorDofIdx_, 0);
297 upIdx_[phaseIdx] = interiorDofIdx_;
298 dnIdx_[phaseIdx] = exteriorDofIdx_;
300 else if (Vin < Vex) {
301 upIdx_[phaseIdx] = exteriorDofIdx_;
302 dnIdx_[phaseIdx] = interiorDofIdx_;
309 upIdx_[phaseIdx] = interiorDofIdx_;
310 dnIdx_[phaseIdx] = exteriorDofIdx_;
313 upIdx_[phaseIdx] = exteriorDofIdx_;
314 dnIdx_[phaseIdx] = interiorDofIdx_;
323 const auto& up = elemCtx.intensiveQuantities(upstreamIdx, timeIdx);
325 if (upstreamIdx == interiorDofIdx_) {
326 volumeFlux_[phaseIdx] =
327 pressureDifference_[phaseIdx] * up.mobility(phaseIdx) * (-trans);
330 volumeFlux_[phaseIdx] =
331 pressureDifference_[phaseIdx] * (Toolbox::value(up.mobility(phaseIdx)) * (-trans));
343 const FluidState& exFluidState)
345 const auto& stencil = elemCtx.stencil(timeIdx);
346 const auto& scvf = stencil.boundaryFace(scvfIdx);
348 interiorDofIdx_ = scvf.interiorIndex();
350 const Scalar trans = transmissibilityBoundary_(elemCtx, scvfIdx, timeIdx);
355 const Scalar g = elemCtx.problem().gravity()[dimWorld - 1];
357 const auto& intQuantsIn = elemCtx.intensiveQuantities(interiorDofIdx_, timeIdx);
364 const Scalar zIn = dofCenterDepth_(elemCtx, interiorDofIdx_, timeIdx);
365 const Scalar zEx = scvf.integrationPos()[dimWorld - 1];
369 const Scalar distZ = zIn - zEx;
371 for (
unsigned phaseIdx = 0; phaseIdx < numPhases; ++phaseIdx) {
372 if (!FluidSystem::phaseIsActive(phaseIdx)) {
378 const Evaluation& rhoIn = intQuantsIn.fluidState().density(phaseIdx);
379 const auto& rhoEx = exFluidState.density(phaseIdx);
380 const Evaluation rhoAvg = (rhoIn + rhoEx) / 2;
382 const Evaluation& pressureInterior = intQuantsIn.fluidState().pressure(phaseIdx);
383 Evaluation pressureExterior = exFluidState.pressure(phaseIdx);
384 pressureExterior += rhoAvg * (distZ * g);
386 pressureDifference_[phaseIdx] = pressureExterior - pressureInterior;
392 if (pressureDifference_[phaseIdx] > 0.0) {
393 upIdx_[phaseIdx] = -1;
394 dnIdx_[phaseIdx] = interiorDofIdx_;
397 upIdx_[phaseIdx] = interiorDofIdx_;
398 dnIdx_[phaseIdx] = -1;
402 if (upstreamIdx == interiorDofIdx_) {
406 const auto& up = elemCtx.intensiveQuantities(upstreamIdx, timeIdx);
408 volumeFlux_[phaseIdx] =
409 pressureDifference_[phaseIdx] * up.mobility(phaseIdx) * (-trans);
414 const auto& matParams =
415 elemCtx.problem().materialLawParams(elemCtx,
418 std::array<typename FluidState::Scalar,numPhases> kr;
419 MaterialLaw::relativePermeabilities(kr, matParams, exFluidState);
421 const auto& mob = kr[phaseIdx] / exFluidState.viscosity(phaseIdx);
422 volumeFlux_[phaseIdx] =
423 pressureDifference_[phaseIdx] * mob * (-trans);