24#ifndef DUMUX_FVPRESSURE2P_HH
25#define DUMUX_FVPRESSURE2P_HH
27#include <dune/common/float_cmp.hh>
134 using PrimaryVariables =
typename SolutionTypes::PrimaryVariables;
138 using ScalarSolutionType =
typename SolutionTypes::ScalarSolution;
142 dim = GridView::dimension, dimWorld = GridView::dimensionworld
146 pw = Indices::pressureW,
147 pn = Indices::pressureNw,
148 pGlobal = Indices::pressureGlobal,
149 sw = Indices::saturationW,
150 sn = Indices::saturationNw,
151 pressureIdx = Indices::pressureIdx,
152 saturationIdx = Indices::saturationIdx,
153 eqIdxPress = Indices::pressureEqIdx,
154 eqIdxSat = Indices::satEqIdx
158 wPhaseIdx = Indices::wPhaseIdx, nPhaseIdx = Indices::nPhaseIdx, numPhases = getPropValue<TypeTag, Properties::NumPhases>()
161 using Element =
typename GridView::Traits::template Codim<0>::Entity;
162 using Intersection =
typename GridView::Intersection;
164 using GlobalPosition =
typename Element::Geometry::GlobalCoordinate;
165 using GravityVector = Dune::FieldVector<Scalar, dimWorld>;
166 using DimMatrix = Dune::FieldMatrix<Scalar, dim, dim>;
179 void getSource(
EntryType& entry,
const Element& element,
const CellData& cellData,
const bool first);
182 void getStorage(
EntryType& entry,
const Element& element,
const CellData& cellData,
const bool first);
185 void getFlux(
EntryType& entry,
const Intersection& intersection,
const CellData& cellData,
const bool first);
189 const Intersection& intersection,
const CellData& cellData,
const bool first);
205 if (!compressibility_)
207 const auto element = *problem_.gridView().template begin<0>();
208 FluidState fluidState;
209 fluidState.setPressure(wPhaseIdx, problem_.referencePressure(element));
210 fluidState.setPressure(nPhaseIdx, problem_.referencePressure(element));
211 fluidState.setTemperature(problem_.temperature(element));
212 fluidState.setSaturation(wPhaseIdx, 1.);
213 fluidState.setSaturation(nPhaseIdx, 0.);
227 PressureSolutionVector pressureOld(this->
pressure());
232 PressureSolutionVector pressureDiff(pressureOld);
235 Scalar pressureNorm = pressureDiff.infinity_norm();
236 pressureNorm /= pressureOld.infinity_norm();
238 while (pressureNorm > 1e-5 && numIter < 10)
244 pressureDiff = pressureOld;
246 pressureNorm = pressureDiff.infinity_norm();
248 pressureNorm /= pressureOld.infinity_norm();
266 timeStep_ = problem_.timeManager().timeStepSize();
269 if (!compressibility_)
272 int size = problem_.gridView().size(0);
273 for (
int i = 0; i < size; i++)
276 switch (saturationType_)
279 sat = problem_.variables().cellData(i).saturation(wPhaseIdx);
282 sat = problem_.variables().cellData(i).saturation(nPhaseIdx);
288 maxError_ = max(maxError_, (sat - 1.0) / timeStep_);
293 maxError_ = max(maxError_, (-sat) / timeStep_);
313 int size = problem_.gridView().size(0);
314 for (
int i = 0; i < size; i++)
316 CellData& cellData = problem_.variables().cellData(i);
317 cellData.fluxData().resetVelocity();
325 for (
const auto& element : elements(problem_.gridView()))
327 asImp_().storePressureSolution(element);
340 int eIdxGlobal = problem_.variables().index(element);
341 CellData& cellData = problem_.variables().cellData(eIdxGlobal);
343 if (compressibility_)
345 density_[wPhaseIdx] = cellData.density(wPhaseIdx);
346 density_[nPhaseIdx] = cellData.density(nPhaseIdx);
349 switch (pressureType_)
353 Scalar pressW = this->
pressure()[eIdxGlobal];
354 Scalar pc = cellData.capillaryPressure();
356 cellData.setPressure(wPhaseIdx, pressW);
357 cellData.setPressure(nPhaseIdx, pressW + pc);
359 Scalar gravityDiff = (problem_.bBoxMax() - element.geometry().center()) * gravity_;
360 Scalar potW = pressW + gravityDiff * density_[wPhaseIdx];
361 Scalar potNw = pressW + pc + gravityDiff * density_[nPhaseIdx];
363 cellData.setPotential(wPhaseIdx, potW);
364 cellData.setPotential(nPhaseIdx, potNw);
370 Scalar pressNw = this->
pressure()[eIdxGlobal];
371 Scalar pc = cellData.capillaryPressure();
373 cellData.setPressure(nPhaseIdx, pressNw);
374 cellData.setPressure(wPhaseIdx, pressNw - pc);
376 Scalar gravityDiff = (problem_.bBoxMax() - element.geometry().center()) * gravity_;
377 Scalar potW = pressNw - pc + gravityDiff * density_[wPhaseIdx];
378 Scalar potNw = pressNw + gravityDiff * density_[nPhaseIdx];
380 cellData.setPotential(wPhaseIdx, potW);
381 cellData.setPotential(nPhaseIdx, potNw);
387 Scalar press = this->
pressure()[eIdxGlobal];
388 cellData.setGlobalPressure(press);
390 Scalar pc = cellData.capillaryPressure();
391 Scalar gravityDiff = (problem_.bBoxMax() - element.geometry().center()) * gravity_;
394 Scalar potW = press - cellData.fracFlowFunc(nPhaseIdx) * pc + gravityDiff * density_[wPhaseIdx];
395 Scalar potNw = press - cellData.fracFlowFunc(wPhaseIdx) * pc + gravityDiff * density_[nPhaseIdx];
397 cellData.setPotential(wPhaseIdx, potW);
398 cellData.setPotential(nPhaseIdx, potNw);
403 cellData.fluxData().resetVelocity();
415 template<
class MultiWriter>
418 int size = problem_.gridView().size(0);
419 ScalarSolutionType *
pressure = writer.allocateManagedBuffer(size);
420 ScalarSolutionType *pressureSecond = 0;
421 ScalarSolutionType *pc = 0;
422 ScalarSolutionType *potentialW = 0;
423 ScalarSolutionType *potentialNw = 0;
424 ScalarSolutionType *mobilityW = 0;
425 ScalarSolutionType *mobilityNW = 0;
427 if (vtkOutputLevel_ > 0)
429 pressureSecond = writer.allocateManagedBuffer(size);
430 pc = writer.allocateManagedBuffer(size);
431 mobilityW = writer.allocateManagedBuffer(size);
432 mobilityNW = writer.allocateManagedBuffer(size);
434 if (vtkOutputLevel_ > 1)
436 potentialW = writer.allocateManagedBuffer(size);
437 potentialNw = writer.allocateManagedBuffer(size);
440 for (
int i = 0; i < size; i++)
442 CellData& cellData = problem_.variables().cellData(i);
444 if (pressureType_ == pw)
446 (*pressure)[i] = cellData.pressure(wPhaseIdx);
447 if (vtkOutputLevel_ > 0)
449 (*pressureSecond)[i] = cellData.pressure(nPhaseIdx);
452 else if (pressureType_ == pn)
454 (*pressure)[i] = cellData.pressure(nPhaseIdx);
455 if (vtkOutputLevel_ > 0)
457 (*pressureSecond)[i] = cellData.pressure(wPhaseIdx);
460 else if (pressureType_ == pGlobal)
462 (*pressure)[i] = cellData.globalPressure();
464 if (vtkOutputLevel_ > 0)
466 (*pc)[i] = cellData.capillaryPressure();
467 (*mobilityW)[i] = cellData.mobility(wPhaseIdx);
468 (*mobilityNW)[i] = cellData.mobility(nPhaseIdx);
469 if (compressibility_)
471 (*mobilityW)[i] = (*mobilityW)[i]/cellData.density(wPhaseIdx);
472 (*mobilityNW)[i] = (*mobilityNW)[i]/cellData.density(nPhaseIdx);
475 if (vtkOutputLevel_ > 1)
477 (*potentialW)[i] = cellData.potential(wPhaseIdx);
478 (*potentialNw)[i] = cellData.potential(nPhaseIdx);
482 if (pressureType_ == pw)
484 writer.attachCellData(*
pressure,
"wetting pressure");
485 if (vtkOutputLevel_ > 0)
487 writer.attachCellData(*pressureSecond,
"nonwetting pressure");
490 else if (pressureType_ == pn)
492 writer.attachCellData(*
pressure,
"nonwetting pressure");
493 if (vtkOutputLevel_ > 0)
495 writer.attachCellData(*pressureSecond,
"wetting pressure");
498 if (pressureType_ == pGlobal)
501 writer.attachCellData(*
pressure,
"global pressure");
504 if (vtkOutputLevel_ > 0)
506 writer.attachCellData(*pc,
"capillary pressure");
507 writer.attachCellData(*mobilityW,
"wetting mobility");
508 writer.attachCellData(*mobilityNW,
"nonwetting mobility");
510 if (vtkOutputLevel_ > 1)
512 writer.attachCellData(*potentialW,
"wetting potential");
513 writer.attachCellData(*potentialNw,
"nonwetting potential");
516 if (compressibility_)
518 if (vtkOutputLevel_ > 0)
520 ScalarSolutionType *densityWetting = writer.allocateManagedBuffer(size);
521 ScalarSolutionType *densityNonwetting = writer.allocateManagedBuffer(size);
522 ScalarSolutionType *viscosityWetting = writer.allocateManagedBuffer(size);
523 ScalarSolutionType *viscosityNonwetting = writer.allocateManagedBuffer(size);
525 for (
int i = 0; i < size; i++)
527 CellData& cellData = problem_.variables().cellData(i);
528 (*densityWetting)[i] = cellData.density(wPhaseIdx);
529 (*densityNonwetting)[i] = cellData.density(nPhaseIdx);
530 (*viscosityWetting)[i] = cellData.viscosity(wPhaseIdx);
531 (*viscosityNonwetting)[i] = cellData.viscosity(nPhaseIdx);
534 writer.attachCellData(*densityWetting,
"wetting density");
535 writer.attachCellData(*densityNonwetting,
"nonwetting density");
536 writer.attachCellData(*viscosityWetting,
"wetting viscosity");
537 writer.attachCellData(*viscosityNonwetting,
"nonwetting viscosity");
548 ParentType(problem), problem_(problem), gravity_(problem.gravity()), maxError_(0.), timeStep_(1.)
550 if (pressureType_ != pw && pressureType_ != pn && pressureType_ != pGlobal)
552 DUNE_THROW(Dune::NotImplemented,
"Pressure type not supported!");
554 if (pressureType_ == pGlobal && compressibility_)
556 DUNE_THROW(Dune::NotImplemented,
"Compressibility not supported for global pressure!");
558 if (saturationType_ != sw && saturationType_ != sn)
560 DUNE_THROW(Dune::NotImplemented,
"Saturation type not supported!");
563 ErrorTermFactor_ = getParam<Scalar>(
"Impet.ErrorTermFactor");
564 ErrorTermLowerBound_ = getParam<Scalar>(
"Impet.ErrorTermLowerBound");
565 ErrorTermUpperBound_ = getParam<Scalar>(
"Impet.ErrorTermUpperBound");
567 density_[wPhaseIdx] = 0.;
568 density_[nPhaseIdx] = 0.;
569 viscosity_[wPhaseIdx] = 0.;
570 viscosity_[nPhaseIdx] = 0.;
572 vtkOutputLevel_ = getParam<int>(
"Vtk.OutputLevel");
577 Implementation &asImp_()
578 {
return *
static_cast<Implementation *
>(
this); }
581 const Implementation &asImp_()
const
582 {
return *
static_cast<const Implementation *
>(
this); }
585 const GravityVector& gravity_;
589 Scalar ErrorTermFactor_;
590 Scalar ErrorTermLowerBound_;
591 Scalar ErrorTermUpperBound_;
593 Scalar density_[numPhases];
594 Scalar viscosity_[numPhases];
598 static const bool compressibility_ = getPropValue<TypeTag, Properties::EnableCompressibility>();
600 static const int pressureType_ = getPropValue<TypeTag, Properties::PressureFormulation>();
602 static const int saturationType_ = getPropValue<TypeTag, Properties::SaturationFormulation>();
612template<
class TypeTag>
614 ,
const CellData& cellData,
const bool first)
617 Scalar volume = element.geometry().volume();
620 PrimaryVariables sourcePhase(0.0);
621 problem_.source(sourcePhase, element);
623 if (!compressibility_)
625 sourcePhase[wPhaseIdx] /= density_[wPhaseIdx];
626 sourcePhase[nPhaseIdx] /= density_[nPhaseIdx];
629 entry[rhs] = volume * (sourcePhase[wPhaseIdx] + sourcePhase[nPhaseIdx]);
656template<
class TypeTag>
658 ,
const CellData& cellData,
const bool first)
661 if (compressibility_ && !first)
664 Scalar volume = element.geometry().volume();
666 Scalar
porosity = problem_.spatialParams().porosity(element);
668 switch (saturationType_)
672 entry[rhs] = -(cellData.volumeCorrection()/timeStep_ *
porosity * volume
673 * (cellData.density(wPhaseIdx) - cellData.density(nPhaseIdx)));
678 entry[rhs] = -(cellData.volumeCorrection()/timeStep_ *
porosity * volume
679 * (cellData.density(nPhaseIdx) - cellData.density(wPhaseIdx)));
684 else if (!compressibility_ && !first)
689 switch (saturationType_)
692 sat = cellData.saturation(wPhaseIdx);
695 sat = cellData.saturation(nPhaseIdx);
699 Scalar volume = element.geometry().volume();
701 Scalar error = (sat > 1.0) ? sat - 1.0 : 0.0;
702 if (sat < 0.0) {error = sat;}
706 Scalar errorAbs = abs(error);
708 if ((errorAbs*timeStep_ > 1e-6) && (errorAbs > ErrorTermLowerBound_ * maxError_) && (!problem_.timeManager().willBeFinished()))
710 entry[rhs] = ErrorTermFactor_ * error * volume;
720template<
class TypeTag>
722 ,
const CellData& cellData,
const bool first)
724 auto elementI = intersection.inside();
725 auto elementJ = intersection.outside();
727 const CellData& cellDataJ = problem_.variables().cellData(problem_.variables().index(elementJ));
730 const GlobalPosition& globalPosI = elementI.geometry().center();
731 const GlobalPosition& globalPosJ = elementJ.geometry().center();
734 Scalar lambdaWI = cellData.mobility(wPhaseIdx);
735 Scalar lambdaNwI = cellData.mobility(nPhaseIdx);
736 Scalar lambdaWJ = cellDataJ.mobility(wPhaseIdx);
737 Scalar lambdaNwJ = cellDataJ.mobility(nPhaseIdx);
740 Scalar pcI = cellData.capillaryPressure();
741 Scalar pcJ = cellDataJ.capillaryPressure();
744 const Dune::FieldVector<Scalar, dim>& unitOuterNormal = intersection.centerUnitOuterNormal();
747 Scalar faceArea = intersection.geometry().volume();
750 GlobalPosition distVec = globalPosJ - globalPosI;
753 Scalar dist = distVec.two_norm();
756 DimMatrix meanPermeability(0);
758 problem_.spatialParams().meanK(meanPermeability, problem_.spatialParams().intrinsicPermeability(elementI),
759 problem_.spatialParams().intrinsicPermeability(elementJ));
765 Scalar rhoMeanNw = 0;
766 if (compressibility_)
768 rhoMeanW = 0.5 * (cellData.density(wPhaseIdx) + cellDataJ.density(wPhaseIdx));
769 rhoMeanNw = 0.5 * (cellData.density(nPhaseIdx) + cellDataJ.density(nPhaseIdx));
773 Scalar potentialDiffW = 0;
774 Scalar potentialDiffNw = 0;
779 potentialDiffW = cellData.potential(wPhaseIdx) - cellDataJ.potential(wPhaseIdx);
780 potentialDiffNw = cellData.potential(nPhaseIdx) - cellDataJ.potential(nPhaseIdx);
782 if (compressibility_)
784 density_[wPhaseIdx] = (potentialDiffW > 0.) ? cellData.density(wPhaseIdx) : cellDataJ.density(wPhaseIdx);
785 density_[nPhaseIdx] = (potentialDiffNw > 0.) ? cellData.density(nPhaseIdx) : cellDataJ.density(nPhaseIdx);
787 density_[wPhaseIdx] = (Dune::FloatCmp::eq<Scalar, Dune::FloatCmp::absolute>(potentialDiffW, 0.0, 1.0e-30)) ? rhoMeanW : density_[wPhaseIdx];
788 density_[nPhaseIdx] = (Dune::FloatCmp::eq<Scalar, Dune::FloatCmp::absolute>(potentialDiffNw, 0.0, 1.0e-30)) ? rhoMeanNw : density_[nPhaseIdx];
790 potentialDiffW = cellData.pressure(wPhaseIdx) - cellDataJ.pressure(wPhaseIdx);
791 potentialDiffNw = cellData.pressure(nPhaseIdx) - cellDataJ.pressure(nPhaseIdx);
793 potentialDiffW += density_[wPhaseIdx] * (distVec * gravity_);
794 potentialDiffNw += density_[nPhaseIdx] * (distVec * gravity_);
799 Scalar lambdaW = (potentialDiffW > 0.) ? lambdaWI : lambdaWJ;
800 lambdaW = (Dune::FloatCmp::eq<Scalar, Dune::FloatCmp::absolute>(potentialDiffW, 0.0, 1.0e-30)) ? 0.5 * (lambdaWI + lambdaWJ) : lambdaW;
801 Scalar lambdaNw = (potentialDiffNw > 0) ? lambdaNwI : lambdaNwJ;
802 lambdaNw = (Dune::FloatCmp::eq<Scalar, Dune::FloatCmp::absolute>(potentialDiffNw, 0.0, 1.0e-30)) ? 0.5 * (lambdaNwI + lambdaNwJ) : lambdaNw;
804 if (compressibility_)
806 density_[wPhaseIdx] = (potentialDiffW > 0.) ? cellData.density(wPhaseIdx) : cellDataJ.density(wPhaseIdx);
807 density_[nPhaseIdx] = (potentialDiffNw > 0.) ? cellData.density(nPhaseIdx) : cellDataJ.density(nPhaseIdx);
809 density_[wPhaseIdx] = (Dune::FloatCmp::eq<Scalar, Dune::FloatCmp::absolute>(potentialDiffW, 0.0, 1.0e-30)) ? rhoMeanW : density_[wPhaseIdx];
810 density_[nPhaseIdx] = (Dune::FloatCmp::eq<Scalar, Dune::FloatCmp::absolute>(potentialDiffNw, 0.0, 1.0e-30)) ? rhoMeanNw : density_[nPhaseIdx];
815 entry[matrix] = (lambdaW + lambdaNw) * scalarPerm / dist * faceArea;
820 Scalar areaScaling = (unitOuterNormal * distVec);
822 entry[rhs] = (lambdaW * density_[wPhaseIdx] + lambdaNw * density_[nPhaseIdx]) * scalarPerm * (gravity_ * distVec) * faceArea * areaScaling;
824 if (pressureType_ == pw)
827 entry[rhs] += 0.5 * (lambdaNwI + lambdaNwJ) * scalarPerm * (pcI - pcJ) / dist * faceArea;
829 else if (pressureType_ == pn)
832 entry[rhs] -= 0.5 * (lambdaWI + lambdaWJ) * scalarPerm * (pcI - pcJ) / dist * faceArea;
844template<
class TypeTag>
846const Intersection& intersection,
const CellData& cellData,
const bool first)
848 auto element = intersection.inside();
851 const GlobalPosition& globalPosI = element.geometry().center();
854 const GlobalPosition& globalPosJ = intersection.geometry().center();
857 Scalar lambdaWI = cellData.mobility(wPhaseIdx);
858 Scalar lambdaNwI = cellData.mobility(nPhaseIdx);
859 Scalar fractionalWI = cellData.fracFlowFunc(wPhaseIdx);
860 Scalar fractionalNwI = cellData.fracFlowFunc(nPhaseIdx);
863 Scalar pcI = cellData.capillaryPressure();
866 int isIndexI = intersection.indexInInside();
869 const Dune::FieldVector<Scalar, dim>& unitOuterNormal = intersection.centerUnitOuterNormal();
872 Scalar faceArea = intersection.geometry().volume();
875 GlobalPosition distVec = globalPosJ - globalPosI;
878 Scalar dist = distVec.two_norm();
880 BoundaryTypes bcType;
881 problem_.boundaryTypes(bcType, intersection);
882 PrimaryVariables boundValues(0.0);
884 if (bcType.isDirichlet(eqIdxPress))
886 problem_.dirichlet(boundValues, intersection);
890 DimMatrix meanPermeability(0);
892 problem_.spatialParams().meanK(meanPermeability,
893 problem_.spatialParams().intrinsicPermeability(element));
901 if (bcType.isDirichlet(eqIdxSat))
903 switch (saturationType_)
907 satW = boundValues[saturationIdx];
908 satNw = 1 - boundValues[saturationIdx];
913 satW = 1 - boundValues[saturationIdx];
914 satNw = boundValues[saturationIdx];
921 satW = cellData.saturation(wPhaseIdx);
922 satNw = cellData.saturation(nPhaseIdx);
925 const Scalar
temperature = problem_.temperature(element);
928 const Scalar pressBound = boundValues[pressureIdx];
935 const auto fluidMatrixInteraction = Deprecated::makePcKrSw(Scalar{}, problem_.spatialParams(), element);
937 const Scalar pcBound = fluidMatrixInteraction.pc(satW);
942 if (pressureType_ == pw)
945 pressNw = pressBound + pcBound;
947 else if (pressureType_ == pn)
949 pressW = pressBound - pcBound;
950 pressNw = pressBound;
953 Scalar densityWBound = density_[wPhaseIdx];
954 Scalar densityNwBound = density_[nPhaseIdx];
955 Scalar viscosityWBound = viscosity_[wPhaseIdx];
956 Scalar viscosityNwBound = viscosity_[nPhaseIdx];
958 Scalar rhoMeanNw = 0;
960 if (compressibility_)
962 FluidState fluidState;
963 fluidState.setSaturation(wPhaseIdx, satW);
964 fluidState.setSaturation(nPhaseIdx, satNw);
966 fluidState.setPressure(wPhaseIdx, pressW);
967 fluidState.setPressure(nPhaseIdx, pressNw);
974 rhoMeanW = 0.5 * (cellData.density(wPhaseIdx) + densityWBound);
975 rhoMeanNw = 0.5 * (cellData.density(nPhaseIdx) + densityNwBound);
978 Scalar lambdaWBound = fluidMatrixInteraction.krw(satW)
980 Scalar lambdaNwBound = fluidMatrixInteraction.krn(satW)
983 Scalar fractionalWBound = lambdaWBound / (lambdaWBound + lambdaNwBound);
984 Scalar fractionalNwBound = lambdaNwBound / (lambdaWBound + lambdaNwBound);
986 Scalar fMeanW = 0.5 * (fractionalWI + fractionalWBound);
987 Scalar fMeanNw = 0.5 * (fractionalNwI + fractionalNwBound);
989 Scalar potentialDiffW = 0;
990 Scalar potentialDiffNw = 0;
994 potentialDiffW = cellData.fluxData().upwindPotential(wPhaseIdx, isIndexI);
995 potentialDiffNw = cellData.fluxData().upwindPotential(nPhaseIdx, isIndexI);
997 if (compressibility_)
999 density_[wPhaseIdx] = (potentialDiffW > 0.) ? cellData.density(wPhaseIdx) : densityWBound;
1000 density_[nPhaseIdx] = (potentialDiffNw > 0.) ? cellData.density(nPhaseIdx) : densityNwBound;
1002 density_[wPhaseIdx] = (Dune::FloatCmp::eq<Scalar, Dune::FloatCmp::absolute>(potentialDiffW, 0.0, 1.0e-30)) ? rhoMeanW : density_[wPhaseIdx];
1003 density_[nPhaseIdx] = (Dune::FloatCmp::eq<Scalar, Dune::FloatCmp::absolute>(potentialDiffNw, 0.0, 1.0e-30)) ? rhoMeanNw : density_[nPhaseIdx];
1007 switch (pressureType_)
1011 potentialDiffW = (cellData.pressure(wPhaseIdx) - pressBound);
1012 potentialDiffNw = (cellData.pressure(nPhaseIdx) - pressBound - pcBound);
1017 potentialDiffW = (cellData.pressure(wPhaseIdx) - pressBound + pcBound);
1018 potentialDiffNw = (cellData.pressure(nPhaseIdx) - pressBound);
1023 potentialDiffW = (cellData.globalPressure() - pressBound - fMeanNw * (pcI - pcBound));
1024 potentialDiffNw = (cellData.globalPressure() - pressBound + fMeanW * (pcI - pcBound));
1029 potentialDiffW += density_[wPhaseIdx] * (distVec * gravity_);
1030 potentialDiffNw += density_[nPhaseIdx] * (distVec * gravity_);
1034 Scalar lambdaW = (potentialDiffW > 0.) ? lambdaWI : lambdaWBound;
1035 lambdaW = (Dune::FloatCmp::eq<Scalar, Dune::FloatCmp::absolute>(potentialDiffW, 0.0, 1.0e-30)) ? 0.5 * (lambdaWI + lambdaWBound) : lambdaW;
1036 Scalar lambdaNw = (potentialDiffNw > 0.) ? lambdaNwI : lambdaNwBound;
1037 lambdaNw = (Dune::FloatCmp::eq<Scalar, Dune::FloatCmp::absolute>(potentialDiffNw, 0.0, 1.0e-30)) ? 0.5 * (lambdaNwI + lambdaNwBound) : lambdaNw;
1039 if (compressibility_)
1041 density_[wPhaseIdx] = (potentialDiffW > 0.) ? cellData.density(wPhaseIdx) : densityWBound;
1042 density_[wPhaseIdx] = (Dune::FloatCmp::eq<Scalar, Dune::FloatCmp::absolute>(potentialDiffW, 0.0, 1.0e-30)) ? rhoMeanW : density_[wPhaseIdx];
1043 density_[nPhaseIdx] = (potentialDiffNw > 0.) ? cellData.density(nPhaseIdx) : densityNwBound;
1044 density_[nPhaseIdx] = (Dune::FloatCmp::eq<Scalar, Dune::FloatCmp::absolute>(potentialDiffNw, 0.0, 1.0e-30)) ? rhoMeanNw : density_[nPhaseIdx];
1049 entry[matrix] = (lambdaW + lambdaNw) * scalarPerm / dist * faceArea;
1050 entry[rhs] = entry[matrix] * pressBound;
1055 Scalar areaScaling = (unitOuterNormal * distVec);
1057 entry[rhs] -= (lambdaW * density_[wPhaseIdx] + lambdaNw * density_[nPhaseIdx]) * scalarPerm * (gravity_ * distVec)
1058 * faceArea * areaScaling;
1060 if (pressureType_ == pw)
1063 entry[rhs] -= 0.5 * (lambdaNwI + lambdaNwBound) * scalarPerm * (pcI - pcBound) / dist * faceArea;
1065 else if (pressureType_ == pn)
1068 entry[rhs] += 0.5 * (lambdaWI + lambdaWBound) * scalarPerm * (pcI - pcBound) / dist * faceArea;
1072 else if (bcType.isNeumann(eqIdxPress))
1074 problem_.neumann(boundValues, intersection);
1076 if (!compressibility_)
1078 boundValues[wPhaseIdx] /= density_[wPhaseIdx];
1079 boundValues[nPhaseIdx] /= density_[nPhaseIdx];
1081 entry[rhs] = -(boundValues[wPhaseIdx] + boundValues[nPhaseIdx]) * faceArea;
1085 DUNE_THROW(Dune::NotImplemented,
"No valid boundary condition type defined for pressure equation!");
1097template<
class TypeTag>
1100 for (
const auto& element : elements(problem_.gridView()))
1102 int eIdxGlobal = problem_.variables().index(element);
1104 CellData& cellData = problem_.variables().cellData(eIdxGlobal);
1106 const Scalar
temperature = problem_.temperature(element);
1109 const Scalar satW = cellData.saturation(wPhaseIdx);
1114 const auto fluidMatrixInteraction = Deprecated::makePcKrSw(Scalar{}, problem_.spatialParams(), element);
1116 const Scalar pc = fluidMatrixInteraction.pc(satW);
1121 if (pressureType_ == pw)
1123 pressW = cellData.pressure(wPhaseIdx);
1124 pressNw = pressW + pc;
1126 else if (pressureType_ == pn)
1128 pressNw = cellData.pressure(nPhaseIdx);
1129 pressW = pressNw - pc;
1132 if (compressibility_)
1134 FluidState& fluidState = cellData.fluidState();
1137 fluidState.setPressure(wPhaseIdx, pressW);
1138 fluidState.setPressure(nPhaseIdx, pressNw);
1147 fluidState.setDensity(wPhaseIdx, density_[wPhaseIdx]);
1148 fluidState.setDensity(nPhaseIdx, density_[nPhaseIdx]);
1151 fluidState.setViscosity(wPhaseIdx, viscosity_[wPhaseIdx]);
1152 fluidState.setViscosity(nPhaseIdx, viscosity_[nPhaseIdx]);
1156 cellData.setCapillaryPressure(pc);
1158 if (pressureType_ != pGlobal)
1160 cellData.setPressure(wPhaseIdx, pressW);
1161 cellData.setPressure(nPhaseIdx, pressNw);
1166 Scalar mobilityW = fluidMatrixInteraction.krw(satW) / viscosity_[wPhaseIdx];
1167 Scalar mobilityNw = fluidMatrixInteraction.krn(satW) / viscosity_[nPhaseIdx];
1169 if (compressibility_)
1171 mobilityW *= density_[wPhaseIdx];
1172 mobilityNw *= density_[nPhaseIdx];
1176 cellData.setMobility(wPhaseIdx, mobilityW);
1177 cellData.setMobility(nPhaseIdx, mobilityNw);
1180 cellData.setFracFlowFunc(wPhaseIdx, mobilityW / (mobilityW + mobilityNw));
1181 cellData.setFracFlowFunc(nPhaseIdx, mobilityNw / (mobilityW + mobilityNw));
1183 const Scalar gravityDiff = (problem_.bBoxMax() - element.geometry().center()) * gravity_;
1185 Scalar potW = pressW + gravityDiff * density_[wPhaseIdx];
1186 Scalar potNw = pressNw + gravityDiff * density_[nPhaseIdx];
1188 if (pressureType_ == pGlobal)
1190 potW = cellData.globalPressure() - cellData.fracFlowFunc(nPhaseIdx) * pc + gravityDiff * density_[wPhaseIdx];
1191 potNw = cellData.globalPressure() - cellData.fracFlowFunc(wPhaseIdx) * pc + gravityDiff * density_[nPhaseIdx];
1194 cellData.setPotential(wPhaseIdx, potW);
1195 cellData.setPotential(nPhaseIdx, potNw);
typename Properties::Detail::GetPropImpl< TypeTag, Property >::type GetProp
get the type of a property (equivalent to old macro GET_PROP(...))
Definition: propertysystem.hh:140
typename Properties::Detail::GetPropImpl< TypeTag, Property >::type::type GetPropType
get the type alias defined in the property (equivalent to old macro GET_PROP_TYPE(....
Definition: propertysystem.hh:149
std::string temperature() noexcept
I/O name of temperature for equilibrium models.
Definition: name.hh:51
std::string viscosity(int phaseIdx) noexcept
I/O name of viscosity for multiphase systems.
Definition: name.hh:74
std::string permeability() noexcept
I/O name of permeability.
Definition: name.hh:143
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
Finite Volume discretization of a two-phase flow pressure equation of the sequential IMPES model.
Definition: 2p/sequential/diffusion/cellcentered/pressure.hh:115
void storePressureSolution(const Element &element)
Stores the pressure solution of a cell.
Definition: 2p/sequential/diffusion/cellcentered/pressure.hh:338
void storePressureSolution()
Globally stores the pressure solution.
Definition: 2p/sequential/diffusion/cellcentered/pressure.hh:322
void getFlux(EntryType &entry, const Intersection &intersection, const CellData &cellData, const bool first)
Function which calculates the flux entry.
Definition: 2p/sequential/diffusion/cellcentered/pressure.hh:721
FVPressure2P(Problem &problem)
Constructs a FVPressure2P object.
Definition: 2p/sequential/diffusion/cellcentered/pressure.hh:547
void updateMaterialLaws()
Updates and stores constitutive relations.
Definition: 2p/sequential/diffusion/cellcentered/pressure.hh:1098
void getFluxOnBoundary(EntryType &entry, const Intersection &intersection, const CellData &cellData, const bool first)
Function which calculates the boundary flux entry.
Definition: 2p/sequential/diffusion/cellcentered/pressure.hh:845
void initialize(bool solveTwice=true)
Initializes the pressure model.
Definition: 2p/sequential/diffusion/cellcentered/pressure.hh:201
void getSource(EntryType &entry, const Element &element, const CellData &cellData, const bool first)
Function which calculates the source entry.
Definition: 2p/sequential/diffusion/cellcentered/pressure.hh:613
void getStorage(EntryType &entry, const Element &element, const CellData &cellData, const bool first)
Function which calculates the storage entry.
Definition: 2p/sequential/diffusion/cellcentered/pressure.hh:657
void addOutputVtkFields(MultiWriter &writer)
Adds pressure output to the output file.
Definition: 2p/sequential/diffusion/cellcentered/pressure.hh:416
void updateVelocity()
Velocity update.
Definition: 2p/sequential/diffusion/cellcentered/pressure.hh:308
void update()
Pressure update.
Definition: 2p/sequential/diffusion/cellcentered/pressure.hh:264
The finite volume base class for the solution of a pressure equation.
Definition: sequential/cellcentered/pressure.hh:49
void assemble(bool first)
Function which assembles the system of equations to be solved.
Definition: sequential/cellcentered/pressure.hh:401
void initialize()
Initialize pressure model.
Definition: sequential/cellcentered/pressure.hh:213
PressureSolution & pressure()
Returns the vector containing the pressure solution.
Definition: sequential/cellcentered/pressure.hh:120
@ rhs
index for the right hand side entry
Definition: sequential/cellcentered/pressure.hh:88
@ matrix
index for the global matrix entry
Definition: sequential/cellcentered/pressure.hh:89
void solve()
Solves the global system of equations to get the spatial distribution of the pressure.
Definition: sequential/cellcentered/pressure.hh:527
void update()
Pressure update.
Definition: sequential/cellcentered/pressure.hh:228
Dune::FieldVector< Scalar, 2 > EntryType
Definition: sequential/cellcentered/pressure.hh:78
Specifies the properties for immiscible 2p diffusion/pressure models.
Finite Volume Diffusion Model.