277 CellData& cellData1, CellData& cellData2,
278 CellData& cellData3, CellData& cellData4,
279 InnerBoundaryVolumeFaces& innerBoundaryVolumeFaces)
286 int level1 = element1.level();
287 int level2 = element2.level();
288 int level3 = element3.level();
289 int level4 = element4.level();
292 int eIdxGlobal1 = problem_.variables().index(element1);
293 int eIdxGlobal2 = problem_.variables().index(element2);
294 int eIdxGlobal3 = problem_.variables().index(element3);
295 int eIdxGlobal4 = problem_.variables().index(element4);
298 Dune::FieldVector < Scalar, 2 * dim > potW(0);
299 Dune::FieldVector < Scalar, 2 * dim > potNw(0);
301 potW[0] = cellData1.potential(wPhaseIdx);
302 potW[1] = cellData2.potential(wPhaseIdx);
303 potW[2] = cellData3.potential(wPhaseIdx);
304 potW[3] = cellData4.potential(wPhaseIdx);
306 potNw[0] = cellData1.potential(nPhaseIdx);
307 potNw[1] = cellData2.potential(nPhaseIdx);
308 potNw[2] = cellData3.potential(nPhaseIdx);
309 potNw[3] = cellData4.potential(nPhaseIdx);
312 Dune::FieldVector < Scalar, numPhases > lambda1(cellData1.mobility(wPhaseIdx));
313 lambda1[nPhaseIdx] = cellData1.mobility(nPhaseIdx);
316 Scalar lambdaTotal1 = lambda1[wPhaseIdx] + lambda1[nPhaseIdx];
319 Dune::FieldVector < Scalar, numPhases > lambda2(cellData2.mobility(wPhaseIdx));
320 lambda2[nPhaseIdx] = cellData2.mobility(nPhaseIdx);
323 Scalar lambdaTotal2 = lambda2[wPhaseIdx] + lambda2[nPhaseIdx];
326 Dune::FieldVector < Scalar, numPhases > lambda3(cellData3.mobility(wPhaseIdx));
327 lambda3[nPhaseIdx] = cellData3.mobility(nPhaseIdx);
330 Scalar lambdaTotal3 = lambda3[wPhaseIdx] + lambda3[nPhaseIdx];
333 Dune::FieldVector < Scalar, numPhases > lambda4(cellData4.mobility(wPhaseIdx));
334 lambda4[nPhaseIdx] = cellData4.mobility(nPhaseIdx);
337 Scalar lambdaTotal4 = lambda4[wPhaseIdx] + lambda4[nPhaseIdx];
340 std::vector < DimVector > lambda(2 * dim);
342 lambda[0][0] = lambdaTotal1;
343 lambda[0][1] = lambdaTotal1;
344 lambda[1][0] = lambdaTotal2;
345 lambda[1][1] = lambdaTotal2;
346 lambda[2][0] = lambdaTotal3;
347 lambda[2][1] = lambdaTotal3;
348 lambda[3][0] = lambdaTotal4;
349 lambda[3][1] = lambdaTotal4;
351 Scalar potentialDiffW12 = 0;
352 Scalar potentialDiffW14 = 0;
353 Scalar potentialDiffW32 = 0;
354 Scalar potentialDiffW34 = 0;
356 Scalar potentialDiffNw12 = 0;
357 Scalar potentialDiffNw14 = 0;
358 Scalar potentialDiffNw32 = 0;
359 Scalar potentialDiffNw34 = 0;
362 Dune::FieldVector < Scalar, 2 * dim > fluxW(0);
363 Dune::FieldVector < Scalar, 2 * dim > fluxNw(0);
365 Dune::FieldMatrix < Scalar, dim, 2 * dim - dim + 1 > T(0);
367 Dune::FieldVector<Scalar, 2 * dim - dim + 1>
u(0);
380 potentialDiffW12 = Tu[1];
389 potentialDiffNw12 = Tu[1];
400 potentialDiffW12 = Tu[1];
409 potentialDiffNw12 = Tu[1];
423 potentialDiffW32 = -Tu[1];
432 potentialDiffNw32 = -Tu[1];
443 potentialDiffW32 = -Tu[1];
452 potentialDiffNw32 = -Tu[1];
466 potentialDiffW34 = Tu[1];
475 potentialDiffNw34 = Tu[1];
486 potentialDiffW34 = Tu[1];
495 potentialDiffNw34 = Tu[1];
509 potentialDiffW14 = -Tu[1];
518 potentialDiffNw14 = -Tu[1];
529 potentialDiffW14 = -Tu[1];
538 potentialDiffNw14 = -Tu[1];
542 cellData1.fluxData().addUpwindPotential(wPhaseIdx, interactionVolume.
getIndexOnElement(0, 0), potentialDiffW12);
543 cellData1.fluxData().addUpwindPotential(nPhaseIdx, interactionVolume.
getIndexOnElement(0, 0), potentialDiffNw12);
544 cellData1.fluxData().addUpwindPotential(wPhaseIdx, interactionVolume.
getIndexOnElement(0, 1), potentialDiffW14);
545 cellData1.fluxData().addUpwindPotential(nPhaseIdx, interactionVolume.
getIndexOnElement(0, 1), potentialDiffNw14);
546 cellData2.fluxData().addUpwindPotential(wPhaseIdx, interactionVolume.
getIndexOnElement(1, 0), -potentialDiffW32);
547 cellData2.fluxData().addUpwindPotential(nPhaseIdx, interactionVolume.
getIndexOnElement(1, 0), -potentialDiffNw32);
548 cellData2.fluxData().addUpwindPotential(wPhaseIdx, interactionVolume.
getIndexOnElement(1, 1), -potentialDiffW12);
549 cellData2.fluxData().addUpwindPotential(nPhaseIdx, interactionVolume.
getIndexOnElement(1, 1), -potentialDiffNw12);
550 cellData3.fluxData().addUpwindPotential(wPhaseIdx, interactionVolume.
getIndexOnElement(2, 0), potentialDiffW34);
551 cellData3.fluxData().addUpwindPotential(nPhaseIdx, interactionVolume.
getIndexOnElement(2, 0), potentialDiffNw34);
552 cellData3.fluxData().addUpwindPotential(wPhaseIdx, interactionVolume.
getIndexOnElement(2, 1), potentialDiffW32);
553 cellData3.fluxData().addUpwindPotential(nPhaseIdx, interactionVolume.
getIndexOnElement(2, 1), potentialDiffNw32);
554 cellData4.fluxData().addUpwindPotential(wPhaseIdx, interactionVolume.
getIndexOnElement(3, 0), -potentialDiffW14);
555 cellData4.fluxData().addUpwindPotential(nPhaseIdx, interactionVolume.
getIndexOnElement(3, 0), -potentialDiffNw14);
556 cellData4.fluxData().addUpwindPotential(wPhaseIdx, interactionVolume.
getIndexOnElement(3, 1), -potentialDiffW34);
557 cellData4.fluxData().addUpwindPotential(nPhaseIdx, interactionVolume.
getIndexOnElement(3, 1), -potentialDiffNw34);
560 Dune::FieldVector < Scalar, numPhases > lambda12Upw(0.0);
561 lambda12Upw[wPhaseIdx] = (potentialDiffW12 >= 0) ? lambda1[wPhaseIdx] : lambda2[wPhaseIdx];
562 lambda12Upw[nPhaseIdx] = (potentialDiffNw12 >= 0) ? lambda1[nPhaseIdx] : lambda2[nPhaseIdx];
565 Dune::FieldVector < Scalar, numPhases > lambda14Upw(0.0);
566 lambda14Upw[wPhaseIdx] = (potentialDiffW14 >= 0) ? lambda1[wPhaseIdx] : lambda4[wPhaseIdx];
567 lambda14Upw[nPhaseIdx] = (potentialDiffNw14 >= 0) ? lambda1[nPhaseIdx] : lambda4[nPhaseIdx];
570 Dune::FieldVector < Scalar, numPhases > lambda32Upw(0.0);
571 lambda32Upw[wPhaseIdx] = (potentialDiffW32 >= 0) ? lambda3[wPhaseIdx] : lambda2[wPhaseIdx];
572 lambda32Upw[nPhaseIdx] = (potentialDiffNw32 >= 0) ? lambda3[nPhaseIdx] : lambda2[nPhaseIdx];
575 Dune::FieldVector < Scalar, numPhases > lambda34Upw(0.0);
576 lambda34Upw[wPhaseIdx] = (potentialDiffW34 >= 0) ? lambda3[wPhaseIdx] : lambda4[wPhaseIdx];
577 lambda34Upw[nPhaseIdx] = (potentialDiffNw34 >= 0) ? lambda3[nPhaseIdx] : lambda4[nPhaseIdx];
579 for (
int i = 0; i < numPhases; i++)
582 DimVector vel12 = interactionVolume.
getNormal(0, 0);
583 DimVector vel14 = interactionVolume.
getNormal(3, 0);
584 DimVector vel23 = interactionVolume.
getNormal(1, 0);
585 DimVector vel21 = interactionVolume.
getNormal(0, 0);
586 DimVector vel34 = interactionVolume.
getNormal(2, 0);
587 DimVector vel32 = interactionVolume.
getNormal(1, 0);
588 DimVector vel41 = interactionVolume.
getNormal(3, 0);
589 DimVector vel43 = interactionVolume.
getNormal(2, 0);
591 Dune::FieldVector < Scalar, 2 * dim > flux(0);
606 vel12 *= flux[0] / (2 * interactionVolume.
getFaceArea(0, 0));
607 vel14 *= flux[3] / (2 * interactionVolume.
getFaceArea(0, 1));
608 vel23 *= flux[1] / (2 * interactionVolume.
getFaceArea(1, 0));
609 vel21 *= flux[0] / (2 * interactionVolume.
getFaceArea(1, 1));
610 vel34 *= flux[2] / (2 * interactionVolume.
getFaceArea(2, 0));
611 vel32 *= flux[1] / (2 * interactionVolume.
getFaceArea(2, 1));
612 vel41 *= flux[3] / (2 * interactionVolume.
getFaceArea(3, 0));
613 vel43 *= flux[2] / (2 * interactionVolume.
getFaceArea(3, 1));
619 else if (level2 < level1)
627 else if (level3 < level2)
635 else if (level4 < level3)
643 else if (level1 < level4)
648 Scalar lambdaT12 = lambda12Upw[wPhaseIdx] + lambda12Upw[nPhaseIdx];
649 Scalar lambdaT14 = lambda14Upw[wPhaseIdx] + lambda14Upw[nPhaseIdx];
650 Scalar lambdaT32 = lambda32Upw[wPhaseIdx] + lambda32Upw[nPhaseIdx];
651 Scalar lambdaT34 = lambda34Upw[wPhaseIdx] + lambda34Upw[nPhaseIdx];
652 Scalar fracFlow12 = (lambdaT12 >
threshold_) ? lambda12Upw[i] / (lambdaT12) : 0.0;
653 Scalar fracFlow14 = (lambdaT14 >
threshold_) ? lambda14Upw[i] / (lambdaT14) : 0.0;
654 Scalar fracFlow32 = (lambdaT32 >
threshold_) ? lambda32Upw[i] / (lambdaT32) : 0.0;
655 Scalar fracFlow34 = (lambdaT34 >
threshold_) ? lambda34Upw[i] / (lambdaT34) : 0.0;
666 if (innerBoundaryVolumeFaces[eIdxGlobal1][interactionVolume.
getIndexOnElement(0, 0)])
670 if (innerBoundaryVolumeFaces[eIdxGlobal1][interactionVolume.
getIndexOnElement(0, 1)])
674 if (innerBoundaryVolumeFaces[eIdxGlobal2][interactionVolume.
getIndexOnElement(1, 0)])
678 if (innerBoundaryVolumeFaces[eIdxGlobal2][interactionVolume.
getIndexOnElement(1, 1)])
682 if (innerBoundaryVolumeFaces[eIdxGlobal3][interactionVolume.
getIndexOnElement(2, 0)])
686 if (innerBoundaryVolumeFaces[eIdxGlobal3][interactionVolume.
getIndexOnElement(2, 1)])
690 if (innerBoundaryVolumeFaces[eIdxGlobal4][interactionVolume.
getIndexOnElement(3, 0)])
694 if (innerBoundaryVolumeFaces[eIdxGlobal4][interactionVolume.
getIndexOnElement(3, 1)])
700 cellData1.fluxData().addVelocity(i, interactionVolume.
getIndexOnElement(0, 0), vel12);
701 cellData1.fluxData().addVelocity(i, interactionVolume.
getIndexOnElement(0, 1), vel14);
702 cellData2.fluxData().addVelocity(i, interactionVolume.
getIndexOnElement(1, 0), vel23);
703 cellData2.fluxData().addVelocity(i, interactionVolume.
getIndexOnElement(1, 1), vel21);
704 cellData3.fluxData().addVelocity(i, interactionVolume.
getIndexOnElement(2, 0), vel34);
705 cellData3.fluxData().addVelocity(i, interactionVolume.
getIndexOnElement(2, 1), vel32);
706 cellData4.fluxData().addVelocity(i, interactionVolume.
getIndexOnElement(3, 0), vel41);
707 cellData4.fluxData().addVelocity(i, interactionVolume.
getIndexOnElement(3, 1), vel43);
710 cellData1.fluxData().setVelocityMarker(interactionVolume.
getIndexOnElement(0, 0));
711 cellData1.fluxData().setVelocityMarker(interactionVolume.
getIndexOnElement(0, 1));
712 cellData2.fluxData().setVelocityMarker(interactionVolume.
getIndexOnElement(1, 0));
713 cellData2.fluxData().setVelocityMarker(interactionVolume.
getIndexOnElement(1, 1));
714 cellData3.fluxData().setVelocityMarker(interactionVolume.
getIndexOnElement(2, 0));
715 cellData3.fluxData().setVelocityMarker(interactionVolume.
getIndexOnElement(2, 1));
716 cellData4.fluxData().setVelocityMarker(interactionVolume.
getIndexOnElement(3, 0));
717 cellData4.fluxData().setVelocityMarker(interactionVolume.
getIndexOnElement(3, 1));
731 CellData& cellData,
int elemIdx)
736 const GlobalPosition& globalPos = element.geometry().center();
739 DimMatrix permeability(problem_.spatialParams().intrinsicPermeability(element));
742 Dune::FieldVector < Scalar, numPhases > lambda(cellData.mobility(wPhaseIdx));
743 lambda[nPhaseIdx] = cellData.mobility(nPhaseIdx);
745 for (
int fIdx = 0; fIdx < dim; fIdx++)
755 const auto refElement = referenceElement(element);
757 const LocalPosition& localPos = refElement.position(boundaryFaceIdx, 1);
759 const GlobalPosition& globalPosFace = element.geometry().global(localPos);
761 DimVector distVec(globalPosFace - globalPos);
762 Scalar dist = distVec.two_norm();
763 DimVector unitDistVec(distVec);
767 Scalar satWBound = cellData.saturation(wPhaseIdx);
776 satWBound = satBound;
781 satWBound = 1 - satBound;
788 const auto fluidMatrixInteraction = problem_.spatialParams().fluidMatrixInteractionAtPos(element.geometry().center());
789 Scalar pcBound = fluidMatrixInteraction.pc(satWBound);
791 Scalar gravityDiffBound = (problem_.bBoxMax() - globalPosFace) *
gravity_
794 pcBound += gravityDiffBound;
796 Dune::FieldVector <Scalar, numPhases> lambdaBound(fluidMatrixInteraction.krw(satWBound));
797 lambdaBound[nPhaseIdx] = fluidMatrixInteraction.krn(satWBound);
798 lambdaBound[wPhaseIdx] /=
viscosity_[wPhaseIdx];
799 lambdaBound[nPhaseIdx] /=
viscosity_[nPhaseIdx];
801 Scalar gdeltaZ = (problem_.bBoxMax()-globalPosFace) *
gravity_;
803 Scalar potentialBoundNw = potentialBoundW;
810 potentialBoundNw += pcBound;
816 potentialBoundW -= pcBound;
821 Scalar potentialDiffW = (cellData.potential(wPhaseIdx) - potentialBoundW) / dist;
822 Scalar potentialDiffNw = (cellData.potential(nPhaseIdx) - potentialBoundNw) / dist;
825 cellData.fluxData().addUpwindPotential(wPhaseIdx, boundaryFaceIdx, potentialDiffW);
826 cellData.fluxData().addUpwindPotential(nPhaseIdx, boundaryFaceIdx, potentialDiffNw);
829 DimVector velocityW(0);
830 DimVector velocityNw(0);
833 DimVector pressGradient = unitDistVec;
834 pressGradient *= (cellData.potential(wPhaseIdx) - potentialBoundW) / dist;
835 permeability.mv(pressGradient, velocityW);
837 pressGradient = unitDistVec;
838 pressGradient *= (cellData.potential(nPhaseIdx) - potentialBoundNw) / dist;
839 permeability.mv(pressGradient, velocityNw);
841 velocityW *= (potentialDiffW >= 0.) ? lambda[wPhaseIdx] : lambdaBound[wPhaseIdx];
842 velocityNw *= (potentialDiffNw >= 0.) ? lambda[nPhaseIdx] : lambdaBound[nPhaseIdx];
849 velocityW += cellData.fluxData().velocity(wPhaseIdx, boundaryFaceIdx);
850 velocityNw += cellData.fluxData().velocity(nPhaseIdx, boundaryFaceIdx);
851 cellData.fluxData().setVelocity(wPhaseIdx, boundaryFaceIdx, velocityW);
852 cellData.fluxData().setVelocity(nPhaseIdx, boundaryFaceIdx, velocityNw);
853 cellData.fluxData().setVelocityMarker(boundaryFaceIdx);
859 const auto refElement = referenceElement(element);
861 const LocalPosition& localPos = refElement.position(boundaryFaceIdx, 1);
863 const GlobalPosition& globalPosFace = element.geometry().global(localPos);
865 DimVector distVec(globalPosFace - globalPos);
866 Scalar dist = distVec.two_norm();
867 DimVector unitDistVec(distVec);
871 PrimaryVariables boundValues(interactionVolume.
getNeumannValues(intVolFaceIdx));
873 boundValues[wPhaseIdx] /=
density_[wPhaseIdx];
874 boundValues[nPhaseIdx] /=
density_[nPhaseIdx];
876 DimVector velocityW(unitDistVec);
877 DimVector velocityNw(unitDistVec);
879 velocityW *= boundValues[wPhaseIdx] / (2 * interactionVolume.
getFaceArea(elemIdx, fIdx));
880 velocityNw *= boundValues[nPhaseIdx]
881 / (2 * interactionVolume.
getFaceArea(elemIdx, fIdx));
884 cellData.fluxData().addUpwindPotential(wPhaseIdx, boundaryFaceIdx, boundValues[wPhaseIdx]);
885 cellData.fluxData().addUpwindPotential(nPhaseIdx, boundaryFaceIdx, boundValues[nPhaseIdx]);
888 velocityW += cellData.fluxData().velocity(wPhaseIdx, boundaryFaceIdx);
889 velocityNw += cellData.fluxData().velocity(nPhaseIdx, boundaryFaceIdx);
890 cellData.fluxData().setVelocity(wPhaseIdx, boundaryFaceIdx, velocityW);
891 cellData.fluxData().setVelocity(nPhaseIdx, boundaryFaceIdx, velocityNw);
892 cellData.fluxData().setVelocityMarker(boundaryFaceIdx);
896 DUNE_THROW(Dune::NotImplemented,
897 "No valid boundary condition type defined for pressure equation!");