24#ifndef DUMUX_FVSATURATION2P_HH
25#define DUMUX_FVSATURATION2P_HH
74template<
class TypeTag>
84 dim = GridView::dimension, dimWorld = GridView::dimensionworld
91 using CapillaryFlux =
typename GET_PROP_TYPE(TypeTag, CapillaryFlux);
92 using GravityFlux =
typename GET_PROP_TYPE(TypeTag, GravityFlux);
94 using SpatialParams =
typename GET_PROP_TYPE(TypeTag, SpatialParams);
95 using MaterialLaw =
typename SpatialParams::MaterialLaw;
97 using Indices =
typename GET_PROP_TYPE(TypeTag, ModelTraits)::Indices;
99 using FluidSystem =
typename GET_PROP_TYPE(TypeTag, FluidSystem);
100 using FluidState =
typename GET_PROP_TYPE(TypeTag, FluidState);
102 using SolutionTypes =
typename GET_PROP(TypeTag, SolutionTypes);
104 using BoundaryTypes =
typename GET_PROP_TYPE(TypeTag, BoundaryTypes);
105 using PrimaryVariables =
typename SolutionTypes::PrimaryVariables;
111 pw = Indices::pressureW,
112 pn = Indices::pressureNw,
113 pGlobal = Indices::pressureGlobal,
114 vw = Indices::velocityW,
115 vn = Indices::velocityNw,
116 vt = Indices::velocityTotal,
117 sw = Indices::saturationW,
118 sn = Indices::saturationNw
122 wPhaseIdx = Indices::wPhaseIdx,
123 nPhaseIdx = Indices::nPhaseIdx,
124 saturationIdx = Indices::saturationIdx,
125 satEqIdx = Indices::satEqIdx,
129 using TransportSolutionType =
typename GET_PROP_TYPE(TypeTag, TransportSolutionType);
131 using Element =
typename GridView::Traits::template Codim<0>::Entity;
132 using Intersection =
typename GridView::Intersection;
134 using GlobalPosition = Dune::FieldVector<Scalar, dimWorld>;
135 using DimVector = Dune::FieldVector<Scalar, dim>;
140 return *capillaryFlux_;
145 return *capillaryFlux_;
150 return *gravityFlux_;
155 return *gravityFlux_;
170 void getFlux(Scalar&
update,
const Intersection& intersection, CellData& cellDataI);
176 void getSource(Scalar&
update,
const Element& element, CellData& cellDataI);
193 int size = problem_.gridView().size(0);
194 transportedQuantity.resize(size);
195 for (
int i = 0; i < size; i++)
197 switch (saturationType_)
201 transportedQuantity[i] = problem_.variables().cellData(i).saturation(wPhaseIdx);
206 transportedQuantity[i] = problem_.variables().cellData(i).saturation(nPhaseIdx);
221 int size = problem_.gridView().size(0);
222 for (
int i = 0; i < size; i++)
224 CellData& cellData = problem_.variables().cellData(i);
225 switch (saturationType_)
229 Scalar sat = transportedQuantity[i];
231 cellData.setSaturation(wPhaseIdx, sat);
232 cellData.setSaturation(nPhaseIdx, 1 - sat);
237 Scalar sat = transportedQuantity[i];
239 cellData.setSaturation(wPhaseIdx,1 -sat);
240 cellData.setSaturation(nPhaseIdx, sat);
253 template<
class DataEntry>
256 return (entry > -1e-6 && entry < 1.0 + 1e-6);
269 asImp_().updateSaturationSolution(updateVec);
280 asImp_().updateSaturationSolution(updateVec, dt);
290 Scalar dt = problem_.timeManager().timeStepSize();
291 int size = problem_.gridView().size(0);
292 for (
int i = 0; i < size; i++)
294 asImp_().updateSaturationSolution(i, updateVec[i][0], dt);
306 int size = problem_.gridView().size(0);
307 for (
int i = 0; i < size; i++)
309 asImp_().updateSaturationSolution(i, updateVec[i][0], dt);
324 CellData& cellData = problem_.variables().cellData(eIdxGlobal);
326 switch (saturationType_)
330 Scalar sat = cellData.saturation(wPhaseIdx) + dt*
update;
332 cellData.setSaturation(wPhaseIdx, sat);
333 cellData.setSaturation(nPhaseIdx, 1 - sat);
338 Scalar sat = cellData.saturation(nPhaseIdx) + dt*
update;
340 cellData.setSaturation(wPhaseIdx,1 -sat);
341 cellData.setSaturation(nPhaseIdx, sat);
359 template<
class MultiWriter>
362 int size = problem_.gridView().size(0);
363 TransportSolutionType *
saturation = writer.allocateManagedBuffer(size);
364 TransportSolutionType *saturationSecond = 0;
366 if (vtkOutputLevel_ > 0)
368 saturationSecond = writer.allocateManagedBuffer(size);
371 for (
int i = 0; i < size; i++)
373 CellData& cellData = problem_.variables().cellData(i);
375 if (saturationType_ == sw)
377 (*saturation)[i] = cellData.saturation(wPhaseIdx);
378 if (vtkOutputLevel_ > 0)
380 (*saturationSecond)[i] = cellData.saturation(nPhaseIdx);
383 else if (saturationType_ == sn)
385 (*saturation)[i] = cellData.saturation(nPhaseIdx);
386 if (vtkOutputLevel_ > 0)
388 (*saturationSecond)[i] = cellData.saturation(wPhaseIdx);
393 if (saturationType_ == sw)
395 writer.attachCellData(*
saturation,
"wetting saturation");
396 if (vtkOutputLevel_ > 0)
398 writer.attachCellData(*saturationSecond,
"nonwetting saturation");
401 else if (saturationType_ == sn)
403 writer.attachCellData(*
saturation,
"nonwetting saturation");
404 if (vtkOutputLevel_ > 0)
406 writer.attachCellData(*saturationSecond,
"wetting saturation");
410 if (
velocity().calculateVelocityInTransport())
411 velocity().addOutputVtkFields(writer);
423 int eIdxGlobal = problem_.variables().index(element);
426 switch (saturationType_)
429 sat = problem_.variables().cellData(eIdxGlobal).saturation(wPhaseIdx);
432 sat = problem_.variables().cellData(eIdxGlobal).saturation(nPhaseIdx);
446 int eIdxGlobal = problem_.variables().index(element);
451 switch (saturationType_)
454 problem_.variables().cellData(eIdxGlobal).setSaturation(wPhaseIdx, sat);
455 problem_.variables().cellData(eIdxGlobal).setSaturation(nPhaseIdx, 1-sat);
458 problem_.variables().cellData(eIdxGlobal).setSaturation(nPhaseIdx, sat);
459 problem_.variables().cellData(eIdxGlobal).setSaturation(wPhaseIdx, 1-sat);
471 ParentType(problem), problem_(problem), threshold_(1e-6),
472 switchNormals_(
getParam<bool>(
"Impet.SwitchNormals"))
474 if (compressibility_ && velocityType_ == vt)
476 DUNE_THROW(Dune::NotImplemented,
477 "Total velocity - global pressure - model cannot be used with compressible fluids!");
479 if (saturationType_ != sw && saturationType_ != sn)
481 DUNE_THROW(Dune::NotImplemented,
"Saturation type not supported!");
483 if (pressureType_ != pw && pressureType_ != pn && pressureType_ != pGlobal)
485 DUNE_THROW(Dune::NotImplemented,
"Pressure type not supported!");
487 if (velocityType_ != vw && velocityType_ != vn && velocityType_ != vt)
489 DUNE_THROW(Dune::NotImplemented,
"Velocity type not supported!");
492 capillaryFlux_ = std::make_shared<CapillaryFlux>(problem);
493 gravityFlux_ = std::make_shared<GravityFlux>(problem);
494 velocity_ = std::make_shared<Velocity>(problem);
496 vtkOutputLevel_ = getParam<int>(
"Vtk.OutputLevel");
497 porosityThreshold_ = getParam<Scalar>(
"Impet.PorosityThreshold");
502 Implementation &asImp_()
503 {
return *
static_cast<Implementation *
>(
this); }
506 const Implementation &asImp_()
const
507 {
return *
static_cast<const Implementation *
>(
this); }
510 std::shared_ptr<Velocity> velocity_;
511 std::shared_ptr<CapillaryFlux> capillaryFlux_;
512 std::shared_ptr<GravityFlux> gravityFlux_;
515 Scalar porosityThreshold_;
520 static const int pressureType_ =
GET_PROP_VALUE(TypeTag, PressureFormulation);
522 Scalar density_[numPhases];
523 Scalar viscosity_[numPhases];
525 const Scalar threshold_;
526 const bool switchNormals_;
540template<
class TypeTag>
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);
654 Scalar capillaryFlux = (flux * unitOuterNormal * faceArea);
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);
677 factorTotal -= capillaryFlux;
678 factorTotal += gravityFlux;
681 this->evalCflFluxFunction().addFlux(lambdaW, lambdaNw, viscosity_[wPhaseIdx],
682 viscosity_[nPhaseIdx], 10 * capillaryFlux, intersection);
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);
733template<
class TypeTag>
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)
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)
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);
872 Scalar capillaryFlux = flux * unitOuterNormal * faceArea;
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);
900 factorTotal -= capillaryFlux;
901 factorTotal += gravityFlux;
904 this->evalCflFluxFunction().addFlux(lambdaW, lambdaNw, viscosity_[wPhaseIdx],
905 viscosity_[nPhaseIdx], 10 * capillaryFlux, intersection);
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);
1044template<
class TypeTag>
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,
1126template<
class TypeTag>
1129 ParentType::initialize();
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.);
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();
1186template<
class TypeTag>
1190 for (
const auto& element : elements(problem_.gridView()))
1192 int eIdxGlobal = problem_.variables().index(element);
1194 CellData& cellData = problem_.variables().cellData(eIdxGlobal);
1197 Scalar satW = cellData.saturation(wPhaseIdx);
1199 Scalar pc = MaterialLaw::pc(problem_.spatialParams().materialLawParams(element), satW);
1201 cellData.setCapillaryPressure(pc);
1204 Scalar mobilityW = MaterialLaw::krw(problem_.spatialParams().materialLawParams(element), satW) / viscosity_[wPhaseIdx];
1205 Scalar mobilityNw = MaterialLaw::krn(problem_.spatialParams().materialLawParams(element), satW) / viscosity_[nPhaseIdx];
1208 cellData.setMobility(wPhaseIdx, mobilityW);
1209 cellData.setMobility(nPhaseIdx, mobilityNw);
1212 cellData.setFracFlowFunc(wPhaseIdx, mobilityW / (mobilityW + mobilityNw));
1213 cellData.setFracFlowFunc(nPhaseIdx, mobilityNw / (mobilityW + mobilityNw));
#define GET_PROP_VALUE(TypeTag, PropTagName)
Definition: propertysystemmacros.hh:282
#define GET_PROP(TypeTag, PropTagName)
Definition: propertysystemmacros.hh:281
#define GET_PROP_TYPE(TypeTag, PropTagName)
Definition: propertysystemmacros.hh:283
Finite Volume discretization of a transport equation.
T getParam(Args &&... args)
A free function to get a parameter from the parameter tree singleton.
Definition: parameters.hh:428
make the local view function available whenever we use the grid geometry
Definition: adapt.hh:29
Property tag EnableCompressibility
Returns whether compressibility is allowed.
Definition: porousmediumflow/2p/sequential/properties.hh:55
Property tag TransportModel
The type of the discretization of a transport model.
Definition: porousmediumflow/sequential/properties.hh:66
Property tag SaturationFormulation
The formulation of the saturation model.
Definition: porousmediumflow/2p/sequential/properties.hh:53
Property tag NumPhases
Number of phases in the system.
Definition: porousmediumflow/sequential/properties.hh:69
Property tag VelocityFormulation
The type of velocity reconstructed for the transport model.
Definition: porousmediumflow/2p/sequential/properties.hh:54
std::string saturation(int phaseIdx) noexcept
I/O name of saturation for multiphase systems.
Definition: name.hh:43
std::string viscosity(int phaseIdx) noexcept
I/O name of viscosity for multiphase systems.
Definition: name.hh:74
std::string density(int phaseIdx) noexcept
I/O name of density for multiphase systems.
Definition: name.hh:65
std::string porosity() noexcept
I/O name of porosity.
Definition: name.hh:139
The finite volume discretization of a saturation transport equation.
Definition: saturation.hh:76
const CapillaryFlux & capillaryFlux() const
Definition: saturation.hh:143
void getFlux(Scalar &update, const Intersection &intersection, CellData &cellDataI)
Function which calculates the flux update.
Definition: saturation.hh:541
Velocity & velocity()
Definition: saturation.hh:159
GravityFlux & gravityFlux()
Definition: saturation.hh:148
void updateTransportedQuantity(TransportSolutionType &updateVec)
Updates the primary transport variable.
Definition: saturation.hh:264
void updateSaturationSolution(int eIdxGlobal, Scalar update, Scalar dt)
Updates the saturation solution of a cell.
Definition: saturation.hh:322
void getFluxOnBoundary(Scalar &update, const Intersection &intersection, CellData &cellDataI)
Function which calculates the boundary flux update.
Definition: saturation.hh:734
void updateSaturationSolution(TransportSolutionType &updateVec)
Globally updates the saturation solution.
Definition: saturation.hh:288
CapillaryFlux & capillaryFlux()
Definition: saturation.hh:138
Velocity & velocity() const
Definition: saturation.hh:164
void updateSaturationSolution(TransportSolutionType &updateVec, Scalar dt)
Globally updates the saturation solution.
Definition: saturation.hh:304
void initialize()
Sets the initial solution.
Definition: saturation.hh:1127
void getTransportedQuantity(TransportSolutionType &transportedQuantity)
Writes the current values of the primary transport variable into the transportedQuantity-vector (come...
Definition: saturation.hh:191
const GravityFlux & gravityFlux() const
Definition: saturation.hh:153
void serializeEntity(std::ostream &outstream, const Element &element)
Function for serialization of the primary transport variable.
Definition: saturation.hh:421
void deserializeEntity(std::istream &instream, const Element &element)
Function for deserialization of the primary transport variable.
Definition: saturation.hh:444
void updateMaterialLaws()
Update the values of the material laws and constitutive relations.
Definition: saturation.hh:1187
void addOutputVtkFields(MultiWriter &writer)
Adds saturation output to the output file.
Definition: saturation.hh:360
FVSaturation2P(Problem &problem)
Constructs a FVSaturation2P object.
Definition: saturation.hh:470
void getSource(Scalar &update, const Element &element, CellData &cellDataI)
Function which calculates the source update.
Definition: saturation.hh:1045
void setTransportedQuantity(TransportSolutionType &transportedQuantity)
Writes the current values of the primary transport variable into the variable container.
Definition: saturation.hh:219
void updateTransportedQuantity(TransportSolutionType &updateVec, Scalar dt)
Updates the primary transport variable.
Definition: saturation.hh:278
bool inPhysicalRange(DataEntry &entry)
Check if saturation is in physical range.
Definition: saturation.hh:254
The finite volume discretization of a transport equation.
Definition: transport.hh:52
bool enableLocalTimeStepping()
Definition: transport.hh:202
void update(const Scalar t, Scalar &dt, TransportSolutionType &updateVec, bool impet=false)
Calculate the update vector.
Definition: transport.hh:270
void innerUpdate(TransportSolutionType &updateVec)
Definition: transport.hh:564
Specifies the properties for immiscible 2p transport.