543 auto elementI = intersection.inside();
544 auto elementJ = intersection.outside();
546 const CellData& cellDataJ = problem_.variables().cellData(problem_.variables().index(elementJ));
549 const GlobalPosition& globalPosI = elementI.geometry().center();
550 const GlobalPosition& globalPosJ = elementJ.geometry().center();
553 Scalar volume = elementI.geometry().volume();
555 Scalar porosity = max(problem_.spatialParams().porosity(elementI), porosityThreshold_);
557 if (compressibility_)
559 viscosity_[wPhaseIdx] = cellDataI.viscosity(wPhaseIdx);
560 viscosity_[nPhaseIdx] = cellDataI.viscosity(nPhaseIdx);
564 int isIndex = intersection.indexInInside();
566 GlobalPosition unitOuterNormal = intersection.centerUnitOuterNormal();
568 unitOuterNormal *= -1.0;
570 Scalar faceArea = intersection.geometry().volume();
572 if (
velocity().calculateVelocityInTransport() && !cellDataI.fluxData().haveVelocity(isIndex))
573 velocity().calculateVelocity(intersection, cellDataI);
576 Scalar factorW = (cellDataI.fluxData().
velocity(wPhaseIdx, isIndex) * unitOuterNormal) * faceArea;
577 Scalar factorNw = (cellDataI.fluxData().
velocity(nPhaseIdx, isIndex) * unitOuterNormal) * faceArea;
578 Scalar factorTotal = factorW + factorNw;
581 GlobalPosition distVec = globalPosJ - globalPosI;
583 Scalar dist = distVec.two_norm();
585 bool takeNeighbor = (elementI.level() < elementJ.level());
588 (takeNeighbor) ? !cellDataJ.fluxData().isUpwindCell(wPhaseIdx, intersection.indexInOutside()) :
589 cellDataI.fluxData().isUpwindCell(wPhaseIdx, isIndex);
591 (takeNeighbor) ? !cellDataJ.fluxData().isUpwindCell(nPhaseIdx, intersection.indexInOutside()) :
592 cellDataI.fluxData().isUpwindCell(nPhaseIdx, isIndex);
600 lambdaW = cellDataI.mobility(wPhaseIdx);
601 if (compressibility_)
603 lambdaW /= cellDataI.density(wPhaseIdx);
608 lambdaW = cellDataJ.mobility(wPhaseIdx);
609 if (compressibility_)
611 lambdaW /= cellDataJ.density(wPhaseIdx);
617 lambdaNw = cellDataI.mobility(nPhaseIdx);
618 if (compressibility_)
620 lambdaNw /= cellDataI.density(nPhaseIdx);
625 lambdaNw = cellDataJ.mobility(nPhaseIdx);
626 if (compressibility_)
628 lambdaNw /= cellDataJ.density(nPhaseIdx);
632 switch (velocityType_)
637 this->evalCflFluxFunction().addFlux(lambdaW, lambdaNw, viscosity_[wPhaseIdx],
638 viscosity_[nPhaseIdx], factorTotal, intersection);
641 Scalar satWI = cellDataI.saturation(wPhaseIdx);
642 Scalar satWJ = cellDataJ.saturation(wPhaseIdx);
644 Scalar pcI = cellDataI.capillaryPressure();
645 Scalar pcJ = cellDataJ.capillaryPressure();
648 GlobalPosition pcGradient = unitOuterNormal;
649 pcGradient *= (pcI - pcJ) / dist;
653 capillaryFlux().getFlux(flux, intersection, satWI, satWJ, pcGradient);
657 gravityFlux().getFlux(flux, intersection, satWI, satWJ);
658 Scalar
gravityFlux = (flux * unitOuterNormal * faceArea);
660 switch (saturationType_)
665 factorTotal *= lambdaW / (lambdaW + lambdaNw);
671 factorTotal *= lambdaNw / (lambdaW + lambdaNw);
681 this->evalCflFluxFunction().addFlux(lambdaW, lambdaNw, viscosity_[wPhaseIdx],
683 this->evalCflFluxFunction().addFlux(lambdaW, lambdaNw, viscosity_[wPhaseIdx],
684 viscosity_[nPhaseIdx], 10 *
gravityFlux, intersection);
690 if (compressibility_)
692 factorW /= cellDataI.density(wPhaseIdx);
693 factorNw /= cellDataI.density(nPhaseIdx);
697 this->evalCflFluxFunction().addFlux(lambdaW, lambdaNw, viscosity_[wPhaseIdx],
698 viscosity_[nPhaseIdx], factorW, intersection, wPhaseIdx);
699 this->evalCflFluxFunction().addFlux(lambdaW, lambdaNw, viscosity_[wPhaseIdx],
700 viscosity_[nPhaseIdx], factorNw, intersection, nPhaseIdx);
706 switch (velocityType_)
709 update -= factorTotal / (volume * porosity);
712 switch (saturationType_)
715 update -= factorW / (volume * porosity);
718 update -= factorNw / (volume * porosity);
736 auto elementI = intersection.inside();
739 const GlobalPosition& globalPosI = elementI.geometry().center();
742 const GlobalPosition& globalPosJ = intersection.geometry().center();
745 Scalar volume = elementI.geometry().volume();
747 Scalar porosity = max(problem_.spatialParams().porosity(elementI), porosityThreshold_);
749 if (compressibility_)
751 viscosity_[wPhaseIdx] = cellDataI.viscosity(wPhaseIdx);
752 viscosity_[nPhaseIdx] = cellDataI.viscosity(nPhaseIdx);
756 int isIndex = intersection.indexInInside();
758 GlobalPosition unitOuterNormal = intersection.centerUnitOuterNormal();
760 unitOuterNormal *= -1.0;
762 Scalar faceArea = intersection.geometry().volume();
764 if (
velocity().calculateVelocityInTransport())
765 velocity().calculateVelocityOnBoundary(intersection, cellDataI);
768 Scalar factorW = (cellDataI.fluxData().
velocity(wPhaseIdx, isIndex) * unitOuterNormal) * faceArea;
769 Scalar factorNw = (cellDataI.fluxData().
velocity(nPhaseIdx, isIndex) * unitOuterNormal) * faceArea;
770 Scalar factorTotal = factorW + factorNw;
773 GlobalPosition distVec = globalPosJ - globalPosI;
776 Scalar dist = distVec.two_norm();
779 BoundaryTypes bcType;
780 problem_.boundaryTypes(bcType, intersection);
781 PrimaryVariables boundValues(0.0);
783 if (bcType.isDirichlet(satEqIdx))
785 problem_.dirichlet(boundValues, intersection);
787 Scalar satBound = boundValues[saturationIdx];
790 Scalar satWI = cellDataI.saturation(wPhaseIdx);
791 Scalar satWBound = 0;
792 switch (saturationType_)
796 satWBound = satBound;
801 satWBound = 1 - satBound;
806 Scalar pcBound = MaterialLaw::pc(problem_.spatialParams().materialLawParams(elementI), satWBound);
812 if (cellDataI.fluxData().isUpwindCell(wPhaseIdx, isIndex))
814 lambdaW = cellDataI.mobility(wPhaseIdx);
815 if (compressibility_)
817 lambdaW /= cellDataI.density(wPhaseIdx);
822 if (compressibility_)
824 lambdaW = MaterialLaw::krw(problem_.spatialParams().materialLawParams(elementI), satWBound)
825 / FluidSystem::viscosity(cellDataI.fluidState(), wPhaseIdx);
829 lambdaW = MaterialLaw::krw(problem_.spatialParams().materialLawParams(elementI), satWBound)
830 / viscosity_[wPhaseIdx];
834 if (cellDataI.fluxData().isUpwindCell(nPhaseIdx, isIndex))
836 lambdaNw = cellDataI.mobility(nPhaseIdx);
837 if (compressibility_)
839 lambdaNw /= cellDataI.density(nPhaseIdx);
844 if (compressibility_)
846 lambdaNw = MaterialLaw::krn(problem_.spatialParams().materialLawParams(elementI), satWBound)
847 / FluidSystem::viscosity(cellDataI.fluidState(), nPhaseIdx);
851 lambdaNw = MaterialLaw::krn(problem_.spatialParams().materialLawParams(elementI), satWBound)
852 / viscosity_[nPhaseIdx];
856 switch (velocityType_)
860 this->evalCflFluxFunction().addFlux(lambdaW, lambdaNw, viscosity_[wPhaseIdx],
861 viscosity_[nPhaseIdx], factorTotal, intersection);
863 Scalar pcI = cellDataI.capillaryPressure();
866 GlobalPosition pcGradient = unitOuterNormal;
867 pcGradient *= (pcI - pcBound) / dist;
871 capillaryFlux().getFlux(flux, intersection, satWI, satWBound, pcGradient);
875 gravityFlux().getFlux(flux, intersection, satWI, satWBound);
876 Scalar
gravityFlux = flux * unitOuterNormal * faceArea;
878 switch (saturationType_)
883 factorTotal *= lambdaW / (lambdaW + lambdaNw);
889 factorTotal *= lambdaNw / (lambdaW + lambdaNw);
891 this->evalCflFluxFunction().addFlux(lambdaW, lambdaNw, viscosity_[wPhaseIdx],
892 viscosity_[nPhaseIdx], factorW, intersection, wPhaseIdx);
893 this->evalCflFluxFunction().addFlux(lambdaW, lambdaNw, viscosity_[wPhaseIdx],
894 viscosity_[nPhaseIdx], factorNw, intersection, nPhaseIdx);
904 this->evalCflFluxFunction().addFlux(lambdaW, lambdaNw, viscosity_[wPhaseIdx],
906 this->evalCflFluxFunction().addFlux(lambdaW, lambdaNw, viscosity_[wPhaseIdx],
907 viscosity_[nPhaseIdx], 10 *
gravityFlux, intersection);
913 if (compressibility_)
915 factorW /= cellDataI.density(wPhaseIdx);
916 factorNw /= cellDataI.density(nPhaseIdx);
920 this->evalCflFluxFunction().addFlux(lambdaW, lambdaNw, viscosity_[wPhaseIdx],
921 viscosity_[nPhaseIdx], factorW, intersection, wPhaseIdx);
922 this->evalCflFluxFunction().addFlux(lambdaW, lambdaNw, viscosity_[wPhaseIdx],
923 viscosity_[nPhaseIdx], factorNw, intersection, nPhaseIdx);
930 if (bcType.isNeumann(satEqIdx))
932 problem_.neumann(boundValues, intersection);
933 factorW = boundValues[wPhaseIdx];
934 factorNw = boundValues[nPhaseIdx];
936 factorNw *= faceArea;
939 Scalar lambdaW, lambdaNw;
941 lambdaW = cellDataI.mobility(wPhaseIdx);
942 lambdaNw = cellDataI.mobility(nPhaseIdx);
943 if (compressibility_)
945 lambdaW /= cellDataI.density(wPhaseIdx);
946 lambdaNw /= cellDataI.density(nPhaseIdx);
947 factorW /= cellDataI.density(wPhaseIdx);
948 factorNw /= cellDataI.density(nPhaseIdx);
952 factorW /= density_[wPhaseIdx];
953 factorNw /= density_[nPhaseIdx];
956 switch (velocityType_)
961 this->evalCflFluxFunction().addFlux(lambdaW, lambdaNw, viscosity_[wPhaseIdx],
962 viscosity_[nPhaseIdx], factorW + factorNw, intersection);
967 this->evalCflFluxFunction().addFlux(lambdaW, lambdaNw, viscosity_[wPhaseIdx],
968 viscosity_[nPhaseIdx], factorW, intersection, wPhaseIdx);
969 this->evalCflFluxFunction().addFlux(lambdaW, lambdaNw, viscosity_[wPhaseIdx],
970 viscosity_[nPhaseIdx], factorNw, intersection, nPhaseIdx);
977 if (bcType.isOutflow(satEqIdx))
980 Scalar lambdaW = cellDataI.mobility(wPhaseIdx);
981 Scalar lambdaNw = cellDataI.mobility(nPhaseIdx);
982 if (compressibility_)
984 lambdaW /= cellDataI.density(wPhaseIdx);
985 lambdaNw /= cellDataI.density(nPhaseIdx);
988 if (velocityType_ == vt)
990 switch (saturationType_)
995 factorTotal *= lambdaW / (lambdaW + lambdaNw);
996 this->evalCflFluxFunction().addFlux(lambdaW, lambdaNw, viscosity_[wPhaseIdx],
997 viscosity_[nPhaseIdx], factorTotal, intersection);
1003 factorTotal *= lambdaNw / (lambdaW + lambdaNw);
1004 this->evalCflFluxFunction().addFlux(lambdaW, lambdaNw, viscosity_[wPhaseIdx],
1005 viscosity_[nPhaseIdx], factorTotal, intersection);
1012 this->evalCflFluxFunction().addFlux(lambdaW, lambdaNw, viscosity_[wPhaseIdx],
1013 viscosity_[nPhaseIdx], factorW, intersection, wPhaseIdx);
1014 this->evalCflFluxFunction().addFlux(lambdaW, lambdaNw, viscosity_[wPhaseIdx],
1015 viscosity_[nPhaseIdx], factorNw, intersection, nPhaseIdx);
1018 switch (velocityType_)
1021 update -= factorTotal / (volume * porosity);
1024 switch (saturationType_)
1027 update -= factorW / (volume * porosity);
1030 update -= factorNw / (volume * porosity);
1048 Scalar volume = element.geometry().volume();
1051 Scalar porosity = max(problem_.spatialParams().porosity(element), porosityThreshold_);
1053 if (compressibility_)
1055 viscosity_[wPhaseIdx] = cellDataI.viscosity(wPhaseIdx);
1056 viscosity_[nPhaseIdx] = cellDataI.viscosity(nPhaseIdx);
1059 PrimaryVariables sourceVec(0.0);
1060 problem_.source(sourceVec, element);
1062 if (compressibility_)
1064 sourceVec[wPhaseIdx] /= cellDataI.density(wPhaseIdx);
1065 sourceVec[nPhaseIdx] /= cellDataI.density(nPhaseIdx);
1069 sourceVec[wPhaseIdx] /= density_[wPhaseIdx];
1070 sourceVec[nPhaseIdx] /= density_[nPhaseIdx];
1074 Scalar lambdaW = cellDataI.mobility(wPhaseIdx);
1075 Scalar lambdaNw = cellDataI.mobility(nPhaseIdx);
1076 if (compressibility_)
1078 lambdaW /= cellDataI.density(wPhaseIdx);
1079 lambdaNw /= cellDataI.density(nPhaseIdx);
1082 switch (saturationType_)
1086 if (sourceVec[wPhaseIdx] < 0 && cellDataI.saturation(wPhaseIdx) < threshold_)
1087 sourceVec[wPhaseIdx] = 0.0;
1089 update += sourceVec[wPhaseIdx] / porosity;
1094 if (sourceVec[nPhaseIdx] < 0 && cellDataI.saturation(nPhaseIdx) < threshold_)
1095 sourceVec[nPhaseIdx] = 0.0;
1097 update += sourceVec[nPhaseIdx] / porosity;
1102 switch (velocityType_)
1107 this->evalCflFluxFunction().addFlux(lambdaW, lambdaNw, viscosity_[wPhaseIdx], viscosity_[nPhaseIdx],
1108 (sourceVec[wPhaseIdx] + sourceVec[nPhaseIdx]) * -1 * volume, element);
1114 this->evalCflFluxFunction().addFlux(lambdaW, lambdaNw, viscosity_[wPhaseIdx],
1115 viscosity_[nPhaseIdx], sourceVec[wPhaseIdx] * -1 * volume, element,
1117 this->evalCflFluxFunction().addFlux(lambdaW, lambdaNw, viscosity_[wPhaseIdx],
1118 viscosity_[nPhaseIdx], sourceVec[nPhaseIdx] * -1 * volume, element,
1131 if (!compressibility_)
1133 const auto element = *problem_.gridView().template begin<0>();
1134 FluidState fluidState;
1135 fluidState.setPressure(wPhaseIdx, problem_.referencePressure(element));
1136 fluidState.setPressure(nPhaseIdx, problem_.referencePressure(element));
1137 fluidState.setTemperature(problem_.temperature(element));
1138 fluidState.setSaturation(wPhaseIdx, 1.);
1139 fluidState.setSaturation(nPhaseIdx, 0.);
1140 density_[wPhaseIdx] = FluidSystem::density(fluidState, wPhaseIdx);
1141 density_[nPhaseIdx] = FluidSystem::density(fluidState, nPhaseIdx);
1142 viscosity_[wPhaseIdx] = FluidSystem::viscosity(fluidState, wPhaseIdx);
1143 viscosity_[nPhaseIdx] = FluidSystem::viscosity(fluidState, nPhaseIdx);
1147 for (
const auto& element : elements(problem_.gridView()))
1149 PrimaryVariables initSol(0.0);
1150 problem_.initial(initSol, element);
1152 int eIdxGlobal = problem_.variables().index(element);
1154 CellData& cellData = problem_.variables().cellData(eIdxGlobal);
1156 switch (saturationType_)
1160 cellData.setSaturation(wPhaseIdx, initSol[saturationIdx]);
1161 cellData.setSaturation(nPhaseIdx, 1 - initSol[saturationIdx]);
1166 cellData.setSaturation(wPhaseIdx,1 -initSol[saturationIdx]);
1167 cellData.setSaturation(nPhaseIdx, initSol[saturationIdx]);
1174 velocity_->initialize();
1175 capillaryFlux_->initialize();
1176 gravityFlux_->initialize();