24#ifndef DUMUX_FVPRESSURE2P_HH
25#define DUMUX_FVPRESSURE2P_HH
27#include <dune/common/float_cmp.hh>
132 using PrimaryVariables =
typename SolutionTypes::PrimaryVariables;
136 using ScalarSolutionType =
typename SolutionTypes::ScalarSolution;
140 dim = GridView::dimension, dimWorld = GridView::dimensionworld
144 pw = Indices::pressureW,
145 pn = Indices::pressureNw,
146 pGlobal = Indices::pressureGlobal,
147 sw = Indices::saturationW,
148 sn = Indices::saturationNw,
149 pressureIdx = Indices::pressureIdx,
150 saturationIdx = Indices::saturationIdx,
151 eqIdxPress = Indices::pressureEqIdx,
152 eqIdxSat = Indices::satEqIdx
156 wPhaseIdx = Indices::wPhaseIdx, nPhaseIdx = Indices::nPhaseIdx, numPhases = getPropValue<TypeTag, Properties::NumPhases>()
159 using Element =
typename GridView::Traits::template Codim<0>::Entity;
160 using Intersection =
typename GridView::Intersection;
162 using GlobalPosition =
typename Element::Geometry::GlobalCoordinate;
163 using GravityVector = Dune::FieldVector<Scalar, dimWorld>;
164 using DimMatrix = Dune::FieldMatrix<Scalar, dim, dim>;
177 void getSource(
EntryType& entry,
const Element& element,
const CellData& cellData,
const bool first);
180 void getStorage(
EntryType& entry,
const Element& element,
const CellData& cellData,
const bool first);
183 void getFlux(
EntryType& entry,
const Intersection& intersection,
const CellData& cellData,
const bool first);
187 const Intersection& intersection,
const CellData& cellData,
const bool first);
203 if (!compressibility_)
205 const auto element = *problem_.gridView().template begin<0>();
206 FluidState fluidState;
207 fluidState.setPressure(wPhaseIdx, problem_.referencePressure(element));
208 fluidState.setPressure(nPhaseIdx, problem_.referencePressure(element));
209 fluidState.setTemperature(problem_.temperature(element));
210 fluidState.setSaturation(wPhaseIdx, 1.);
211 fluidState.setSaturation(nPhaseIdx, 0.);
225 PressureSolutionVector pressureOld(this->
pressure());
230 PressureSolutionVector pressureDiff(pressureOld);
233 Scalar pressureNorm = pressureDiff.infinity_norm();
234 pressureNorm /= pressureOld.infinity_norm();
236 while (pressureNorm > 1e-5 && numIter < 10)
242 pressureDiff = pressureOld;
244 pressureNorm = pressureDiff.infinity_norm();
246 pressureNorm /= pressureOld.infinity_norm();
264 timeStep_ = problem_.timeManager().timeStepSize();
267 if (!compressibility_)
270 int size = problem_.gridView().size(0);
271 for (
int i = 0; i < size; i++)
274 switch (saturationType_)
277 sat = problem_.variables().cellData(i).saturation(wPhaseIdx);
280 sat = problem_.variables().cellData(i).saturation(nPhaseIdx);
286 maxError_ = max(maxError_, (sat - 1.0) / timeStep_);
291 maxError_ = max(maxError_, (-sat) / timeStep_);
311 int size = problem_.gridView().size(0);
312 for (
int i = 0; i < size; i++)
314 CellData& cellData = problem_.variables().cellData(i);
315 cellData.fluxData().resetVelocity();
323 for (
const auto& element : elements(problem_.gridView()))
325 asImp_().storePressureSolution(element);
338 int eIdxGlobal = problem_.variables().index(element);
339 CellData& cellData = problem_.variables().cellData(eIdxGlobal);
341 if (compressibility_)
343 density_[wPhaseIdx] = cellData.density(wPhaseIdx);
344 density_[nPhaseIdx] = cellData.density(nPhaseIdx);
347 switch (pressureType_)
351 Scalar pressW = this->
pressure()[eIdxGlobal];
352 Scalar pc = cellData.capillaryPressure();
354 cellData.setPressure(wPhaseIdx, pressW);
355 cellData.setPressure(nPhaseIdx, pressW + pc);
357 Scalar gravityDiff = (problem_.bBoxMax() - element.geometry().center()) * gravity_;
358 Scalar potW = pressW + gravityDiff * density_[wPhaseIdx];
359 Scalar potNw = pressW + pc + gravityDiff * density_[nPhaseIdx];
361 cellData.setPotential(wPhaseIdx, potW);
362 cellData.setPotential(nPhaseIdx, potNw);
368 Scalar pressNw = this->
pressure()[eIdxGlobal];
369 Scalar pc = cellData.capillaryPressure();
371 cellData.setPressure(nPhaseIdx, pressNw);
372 cellData.setPressure(wPhaseIdx, pressNw - pc);
374 Scalar gravityDiff = (problem_.bBoxMax() - element.geometry().center()) * gravity_;
375 Scalar potW = pressNw - pc + gravityDiff * density_[wPhaseIdx];
376 Scalar potNw = pressNw + gravityDiff * density_[nPhaseIdx];
378 cellData.setPotential(wPhaseIdx, potW);
379 cellData.setPotential(nPhaseIdx, potNw);
385 Scalar press = this->
pressure()[eIdxGlobal];
386 cellData.setGlobalPressure(press);
388 Scalar pc = cellData.capillaryPressure();
389 Scalar gravityDiff = (problem_.bBoxMax() - element.geometry().center()) * gravity_;
392 Scalar potW = press - cellData.fracFlowFunc(nPhaseIdx) * pc + gravityDiff * density_[wPhaseIdx];
393 Scalar potNw = press - cellData.fracFlowFunc(wPhaseIdx) * pc + gravityDiff * density_[nPhaseIdx];
395 cellData.setPotential(wPhaseIdx, potW);
396 cellData.setPotential(nPhaseIdx, potNw);
401 cellData.fluxData().resetVelocity();
413 template<
class MultiWriter>
416 int size = problem_.gridView().size(0);
417 ScalarSolutionType *
pressure = writer.allocateManagedBuffer(size);
418 ScalarSolutionType *pressureSecond = 0;
419 ScalarSolutionType *pc = 0;
420 ScalarSolutionType *potentialW = 0;
421 ScalarSolutionType *potentialNw = 0;
422 ScalarSolutionType *mobilityW = 0;
423 ScalarSolutionType *mobilityNW = 0;
425 if (vtkOutputLevel_ > 0)
427 pressureSecond = writer.allocateManagedBuffer(size);
428 pc = writer.allocateManagedBuffer(size);
429 mobilityW = writer.allocateManagedBuffer(size);
430 mobilityNW = writer.allocateManagedBuffer(size);
432 if (vtkOutputLevel_ > 1)
434 potentialW = writer.allocateManagedBuffer(size);
435 potentialNw = writer.allocateManagedBuffer(size);
438 for (
int i = 0; i < size; i++)
440 CellData& cellData = problem_.variables().cellData(i);
442 if (pressureType_ == pw)
444 (*pressure)[i] = cellData.pressure(wPhaseIdx);
445 if (vtkOutputLevel_ > 0)
447 (*pressureSecond)[i] = cellData.pressure(nPhaseIdx);
450 else if (pressureType_ == pn)
452 (*pressure)[i] = cellData.pressure(nPhaseIdx);
453 if (vtkOutputLevel_ > 0)
455 (*pressureSecond)[i] = cellData.pressure(wPhaseIdx);
458 else if (pressureType_ == pGlobal)
460 (*pressure)[i] = cellData.globalPressure();
462 if (vtkOutputLevel_ > 0)
464 (*pc)[i] = cellData.capillaryPressure();
465 (*mobilityW)[i] = cellData.mobility(wPhaseIdx);
466 (*mobilityNW)[i] = cellData.mobility(nPhaseIdx);
467 if (compressibility_)
469 (*mobilityW)[i] = (*mobilityW)[i]/cellData.density(wPhaseIdx);
470 (*mobilityNW)[i] = (*mobilityNW)[i]/cellData.density(nPhaseIdx);
473 if (vtkOutputLevel_ > 1)
475 (*potentialW)[i] = cellData.potential(wPhaseIdx);
476 (*potentialNw)[i] = cellData.potential(nPhaseIdx);
480 if (pressureType_ == pw)
482 writer.attachCellData(*
pressure,
"wetting pressure");
483 if (vtkOutputLevel_ > 0)
485 writer.attachCellData(*pressureSecond,
"nonwetting pressure");
488 else if (pressureType_ == pn)
490 writer.attachCellData(*
pressure,
"nonwetting pressure");
491 if (vtkOutputLevel_ > 0)
493 writer.attachCellData(*pressureSecond,
"wetting pressure");
496 if (pressureType_ == pGlobal)
499 writer.attachCellData(*
pressure,
"global pressure");
502 if (vtkOutputLevel_ > 0)
504 writer.attachCellData(*pc,
"capillary pressure");
505 writer.attachCellData(*mobilityW,
"wetting mobility");
506 writer.attachCellData(*mobilityNW,
"nonwetting mobility");
508 if (vtkOutputLevel_ > 1)
510 writer.attachCellData(*potentialW,
"wetting potential");
511 writer.attachCellData(*potentialNw,
"nonwetting potential");
514 if (compressibility_)
516 if (vtkOutputLevel_ > 0)
518 ScalarSolutionType *densityWetting = writer.allocateManagedBuffer(size);
519 ScalarSolutionType *densityNonwetting = writer.allocateManagedBuffer(size);
520 ScalarSolutionType *viscosityWetting = writer.allocateManagedBuffer(size);
521 ScalarSolutionType *viscosityNonwetting = writer.allocateManagedBuffer(size);
523 for (
int i = 0; i < size; i++)
525 CellData& cellData = problem_.variables().cellData(i);
526 (*densityWetting)[i] = cellData.density(wPhaseIdx);
527 (*densityNonwetting)[i] = cellData.density(nPhaseIdx);
528 (*viscosityWetting)[i] = cellData.viscosity(wPhaseIdx);
529 (*viscosityNonwetting)[i] = cellData.viscosity(nPhaseIdx);
532 writer.attachCellData(*densityWetting,
"wetting density");
533 writer.attachCellData(*densityNonwetting,
"nonwetting density");
534 writer.attachCellData(*viscosityWetting,
"wetting viscosity");
535 writer.attachCellData(*viscosityNonwetting,
"nonwetting viscosity");
546 ParentType(problem), problem_(problem), gravity_(problem.gravity()), maxError_(0.), timeStep_(1.)
548 if (pressureType_ != pw && pressureType_ != pn && pressureType_ != pGlobal)
550 DUNE_THROW(Dune::NotImplemented,
"Pressure type not supported!");
552 if (pressureType_ == pGlobal && compressibility_)
554 DUNE_THROW(Dune::NotImplemented,
"Compressibility not supported for global pressure!");
556 if (saturationType_ != sw && saturationType_ != sn)
558 DUNE_THROW(Dune::NotImplemented,
"Saturation type not supported!");
561 ErrorTermFactor_ = getParam<Scalar>(
"Impet.ErrorTermFactor");
562 ErrorTermLowerBound_ = getParam<Scalar>(
"Impet.ErrorTermLowerBound");
563 ErrorTermUpperBound_ = getParam<Scalar>(
"Impet.ErrorTermUpperBound");
565 density_[wPhaseIdx] = 0.;
566 density_[nPhaseIdx] = 0.;
567 viscosity_[wPhaseIdx] = 0.;
568 viscosity_[nPhaseIdx] = 0.;
570 vtkOutputLevel_ = getParam<int>(
"Vtk.OutputLevel");
575 Implementation &asImp_()
576 {
return *
static_cast<Implementation *
>(
this); }
579 const Implementation &asImp_()
const
580 {
return *
static_cast<const Implementation *
>(
this); }
583 const GravityVector& gravity_;
587 Scalar ErrorTermFactor_;
588 Scalar ErrorTermLowerBound_;
589 Scalar ErrorTermUpperBound_;
591 Scalar density_[numPhases];
592 Scalar viscosity_[numPhases];
596 static const bool compressibility_ = getPropValue<TypeTag, Properties::EnableCompressibility>();
598 static const int pressureType_ = getPropValue<TypeTag, Properties::PressureFormulation>();
600 static const int saturationType_ = getPropValue<TypeTag, Properties::SaturationFormulation>();
610template<
class TypeTag>
612 ,
const CellData& cellData,
const bool first)
615 Scalar
volume = element.geometry().volume();
618 PrimaryVariables sourcePhase(0.0);
619 problem_.source(sourcePhase, element);
621 if (!compressibility_)
623 sourcePhase[wPhaseIdx] /= density_[wPhaseIdx];
624 sourcePhase[nPhaseIdx] /= density_[nPhaseIdx];
627 entry[rhs] =
volume * (sourcePhase[wPhaseIdx] + sourcePhase[nPhaseIdx]);
654template<
class TypeTag>
656 ,
const CellData& cellData,
const bool first)
659 if (compressibility_ && !first)
662 Scalar
volume = element.geometry().volume();
664 Scalar
porosity = problem_.spatialParams().porosity(element);
666 switch (saturationType_)
670 entry[rhs] = -(cellData.volumeCorrection()/timeStep_ *
porosity *
volume
671 * (cellData.density(wPhaseIdx) - cellData.density(nPhaseIdx)));
676 entry[rhs] = -(cellData.volumeCorrection()/timeStep_ *
porosity *
volume
677 * (cellData.density(nPhaseIdx) - cellData.density(wPhaseIdx)));
682 else if (!compressibility_ && !first)
687 switch (saturationType_)
690 sat = cellData.saturation(wPhaseIdx);
693 sat = cellData.saturation(nPhaseIdx);
697 Scalar
volume = element.geometry().volume();
699 Scalar error = (sat > 1.0) ? sat - 1.0 : 0.0;
700 if (sat < 0.0) {error = sat;}
704 Scalar errorAbs = abs(error);
706 if ((errorAbs*timeStep_ > 1e-6) && (errorAbs > ErrorTermLowerBound_ * maxError_) && (!problem_.timeManager().willBeFinished()))
708 entry[rhs] = ErrorTermFactor_ * error *
volume;
718template<
class TypeTag>
720 ,
const CellData& cellData,
const bool first)
722 auto elementI = intersection.inside();
723 auto elementJ = intersection.outside();
725 const CellData& cellDataJ = problem_.variables().cellData(problem_.variables().index(elementJ));
728 const GlobalPosition& globalPosI = elementI.geometry().center();
729 const GlobalPosition& globalPosJ = elementJ.geometry().center();
732 Scalar lambdaWI = cellData.mobility(wPhaseIdx);
733 Scalar lambdaNwI = cellData.mobility(nPhaseIdx);
734 Scalar lambdaWJ = cellDataJ.mobility(wPhaseIdx);
735 Scalar lambdaNwJ = cellDataJ.mobility(nPhaseIdx);
738 Scalar pcI = cellData.capillaryPressure();
739 Scalar pcJ = cellDataJ.capillaryPressure();
742 const Dune::FieldVector<Scalar, dim>& unitOuterNormal = intersection.centerUnitOuterNormal();
745 Scalar faceArea = intersection.geometry().volume();
748 GlobalPosition distVec = globalPosJ - globalPosI;
751 Scalar dist = distVec.two_norm();
754 DimMatrix meanPermeability(0);
756 problem_.spatialParams().meanK(meanPermeability, problem_.spatialParams().intrinsicPermeability(elementI),
757 problem_.spatialParams().intrinsicPermeability(elementJ));
763 Scalar rhoMeanNw = 0;
764 if (compressibility_)
766 rhoMeanW = 0.5 * (cellData.density(wPhaseIdx) + cellDataJ.density(wPhaseIdx));
767 rhoMeanNw = 0.5 * (cellData.density(nPhaseIdx) + cellDataJ.density(nPhaseIdx));
771 Scalar potentialDiffW = 0;
772 Scalar potentialDiffNw = 0;
777 potentialDiffW = cellData.potential(wPhaseIdx) - cellDataJ.potential(wPhaseIdx);
778 potentialDiffNw = cellData.potential(nPhaseIdx) - cellDataJ.potential(nPhaseIdx);
780 if (compressibility_)
782 density_[wPhaseIdx] = (potentialDiffW > 0.) ? cellData.density(wPhaseIdx) : cellDataJ.density(wPhaseIdx);
783 density_[nPhaseIdx] = (potentialDiffNw > 0.) ? cellData.density(nPhaseIdx) : cellDataJ.density(nPhaseIdx);
785 density_[wPhaseIdx] = (Dune::FloatCmp::eq<Scalar, Dune::FloatCmp::absolute>(potentialDiffW, 0.0, 1.0e-30)) ? rhoMeanW : density_[wPhaseIdx];
786 density_[nPhaseIdx] = (Dune::FloatCmp::eq<Scalar, Dune::FloatCmp::absolute>(potentialDiffNw, 0.0, 1.0e-30)) ? rhoMeanNw : density_[nPhaseIdx];
788 potentialDiffW = cellData.pressure(wPhaseIdx) - cellDataJ.pressure(wPhaseIdx);
789 potentialDiffNw = cellData.pressure(nPhaseIdx) - cellDataJ.pressure(nPhaseIdx);
791 potentialDiffW += density_[wPhaseIdx] * (distVec * gravity_);
792 potentialDiffNw += density_[nPhaseIdx] * (distVec * gravity_);
797 Scalar lambdaW = (potentialDiffW > 0.) ? lambdaWI : lambdaWJ;
798 lambdaW = (Dune::FloatCmp::eq<Scalar, Dune::FloatCmp::absolute>(potentialDiffW, 0.0, 1.0e-30)) ? 0.5 * (lambdaWI + lambdaWJ) : lambdaW;
799 Scalar lambdaNw = (potentialDiffNw > 0) ? lambdaNwI : lambdaNwJ;
800 lambdaNw = (Dune::FloatCmp::eq<Scalar, Dune::FloatCmp::absolute>(potentialDiffNw, 0.0, 1.0e-30)) ? 0.5 * (lambdaNwI + lambdaNwJ) : lambdaNw;
802 if (compressibility_)
804 density_[wPhaseIdx] = (potentialDiffW > 0.) ? cellData.density(wPhaseIdx) : cellDataJ.density(wPhaseIdx);
805 density_[nPhaseIdx] = (potentialDiffNw > 0.) ? cellData.density(nPhaseIdx) : cellDataJ.density(nPhaseIdx);
807 density_[wPhaseIdx] = (Dune::FloatCmp::eq<Scalar, Dune::FloatCmp::absolute>(potentialDiffW, 0.0, 1.0e-30)) ? rhoMeanW : density_[wPhaseIdx];
808 density_[nPhaseIdx] = (Dune::FloatCmp::eq<Scalar, Dune::FloatCmp::absolute>(potentialDiffNw, 0.0, 1.0e-30)) ? rhoMeanNw : density_[nPhaseIdx];
813 entry[matrix] = (lambdaW + lambdaNw) * scalarPerm / dist * faceArea;
818 Scalar areaScaling = (unitOuterNormal * distVec);
820 entry[rhs] = (lambdaW * density_[wPhaseIdx] + lambdaNw * density_[nPhaseIdx]) * scalarPerm * (gravity_ * distVec) * faceArea * areaScaling;
822 if (pressureType_ == pw)
825 entry[rhs] += 0.5 * (lambdaNwI + lambdaNwJ) * scalarPerm * (pcI - pcJ) / dist * faceArea;
827 else if (pressureType_ == pn)
830 entry[rhs] -= 0.5 * (lambdaWI + lambdaWJ) * scalarPerm * (pcI - pcJ) / dist * faceArea;
842template<
class TypeTag>
844const Intersection& intersection,
const CellData& cellData,
const bool first)
846 auto element = intersection.inside();
849 const GlobalPosition& globalPosI = element.geometry().center();
852 const GlobalPosition& globalPosJ = intersection.geometry().center();
855 Scalar lambdaWI = cellData.mobility(wPhaseIdx);
856 Scalar lambdaNwI = cellData.mobility(nPhaseIdx);
857 Scalar fractionalWI = cellData.fracFlowFunc(wPhaseIdx);
858 Scalar fractionalNwI = cellData.fracFlowFunc(nPhaseIdx);
861 Scalar pcI = cellData.capillaryPressure();
864 int isIndexI = intersection.indexInInside();
867 const Dune::FieldVector<Scalar, dim>& unitOuterNormal = intersection.centerUnitOuterNormal();
870 Scalar faceArea = intersection.geometry().volume();
873 GlobalPosition distVec = globalPosJ - globalPosI;
876 Scalar dist = distVec.two_norm();
878 BoundaryTypes bcType;
879 problem_.boundaryTypes(bcType, intersection);
880 PrimaryVariables boundValues(0.0);
882 if (bcType.isDirichlet(eqIdxPress))
884 problem_.dirichlet(boundValues, intersection);
888 DimMatrix meanPermeability(0);
890 problem_.spatialParams().meanK(meanPermeability,
891 problem_.spatialParams().intrinsicPermeability(element));
899 if (bcType.isDirichlet(eqIdxSat))
901 switch (saturationType_)
905 satW = boundValues[saturationIdx];
906 satNw = 1 - boundValues[saturationIdx];
911 satW = 1 - boundValues[saturationIdx];
912 satNw = boundValues[saturationIdx];
919 satW = cellData.saturation(wPhaseIdx);
920 satNw = cellData.saturation(nPhaseIdx);
923 const Scalar
temperature = problem_.temperature(element);
926 const Scalar pressBound = boundValues[pressureIdx];
930 const auto fluidMatrixInteraction = problem_.spatialParams().fluidMatrixInteractionAtPos(element.geometry().center());
931 const Scalar pcBound = fluidMatrixInteraction.pc(satW);
936 if (pressureType_ == pw)
939 pressNw = pressBound + pcBound;
941 else if (pressureType_ == pn)
943 pressW = pressBound - pcBound;
944 pressNw = pressBound;
947 Scalar densityWBound = density_[wPhaseIdx];
948 Scalar densityNwBound = density_[nPhaseIdx];
949 Scalar viscosityWBound = viscosity_[wPhaseIdx];
950 Scalar viscosityNwBound = viscosity_[nPhaseIdx];
952 Scalar rhoMeanNw = 0;
954 if (compressibility_)
956 FluidState fluidState;
957 fluidState.setSaturation(wPhaseIdx, satW);
958 fluidState.setSaturation(nPhaseIdx, satNw);
960 fluidState.setPressure(wPhaseIdx, pressW);
961 fluidState.setPressure(nPhaseIdx, pressNw);
968 rhoMeanW = 0.5 * (cellData.density(wPhaseIdx) + densityWBound);
969 rhoMeanNw = 0.5 * (cellData.density(nPhaseIdx) + densityNwBound);
972 Scalar lambdaWBound = fluidMatrixInteraction.krw(satW)
974 Scalar lambdaNwBound = fluidMatrixInteraction.krn(satW)
977 Scalar fractionalWBound = lambdaWBound / (lambdaWBound + lambdaNwBound);
978 Scalar fractionalNwBound = lambdaNwBound / (lambdaWBound + lambdaNwBound);
980 Scalar fMeanW = 0.5 * (fractionalWI + fractionalWBound);
981 Scalar fMeanNw = 0.5 * (fractionalNwI + fractionalNwBound);
983 Scalar potentialDiffW = 0;
984 Scalar potentialDiffNw = 0;
988 potentialDiffW = cellData.fluxData().upwindPotential(wPhaseIdx, isIndexI);
989 potentialDiffNw = cellData.fluxData().upwindPotential(nPhaseIdx, isIndexI);
991 if (compressibility_)
993 density_[wPhaseIdx] = (potentialDiffW > 0.) ? cellData.density(wPhaseIdx) : densityWBound;
994 density_[nPhaseIdx] = (potentialDiffNw > 0.) ? cellData.density(nPhaseIdx) : densityNwBound;
996 density_[wPhaseIdx] = (Dune::FloatCmp::eq<Scalar, Dune::FloatCmp::absolute>(potentialDiffW, 0.0, 1.0e-30)) ? rhoMeanW : density_[wPhaseIdx];
997 density_[nPhaseIdx] = (Dune::FloatCmp::eq<Scalar, Dune::FloatCmp::absolute>(potentialDiffNw, 0.0, 1.0e-30)) ? rhoMeanNw : density_[nPhaseIdx];
1001 switch (pressureType_)
1005 potentialDiffW = (cellData.pressure(wPhaseIdx) - pressBound);
1006 potentialDiffNw = (cellData.pressure(nPhaseIdx) - pressBound - pcBound);
1011 potentialDiffW = (cellData.pressure(wPhaseIdx) - pressBound + pcBound);
1012 potentialDiffNw = (cellData.pressure(nPhaseIdx) - pressBound);
1017 potentialDiffW = (cellData.globalPressure() - pressBound - fMeanNw * (pcI - pcBound));
1018 potentialDiffNw = (cellData.globalPressure() - pressBound + fMeanW * (pcI - pcBound));
1023 potentialDiffW += density_[wPhaseIdx] * (distVec * gravity_);
1024 potentialDiffNw += density_[nPhaseIdx] * (distVec * gravity_);
1028 Scalar lambdaW = (potentialDiffW > 0.) ? lambdaWI : lambdaWBound;
1029 lambdaW = (Dune::FloatCmp::eq<Scalar, Dune::FloatCmp::absolute>(potentialDiffW, 0.0, 1.0e-30)) ? 0.5 * (lambdaWI + lambdaWBound) : lambdaW;
1030 Scalar lambdaNw = (potentialDiffNw > 0.) ? lambdaNwI : lambdaNwBound;
1031 lambdaNw = (Dune::FloatCmp::eq<Scalar, Dune::FloatCmp::absolute>(potentialDiffNw, 0.0, 1.0e-30)) ? 0.5 * (lambdaNwI + lambdaNwBound) : lambdaNw;
1033 if (compressibility_)
1035 density_[wPhaseIdx] = (potentialDiffW > 0.) ? cellData.density(wPhaseIdx) : densityWBound;
1036 density_[wPhaseIdx] = (Dune::FloatCmp::eq<Scalar, Dune::FloatCmp::absolute>(potentialDiffW, 0.0, 1.0e-30)) ? rhoMeanW : density_[wPhaseIdx];
1037 density_[nPhaseIdx] = (potentialDiffNw > 0.) ? cellData.density(nPhaseIdx) : densityNwBound;
1038 density_[nPhaseIdx] = (Dune::FloatCmp::eq<Scalar, Dune::FloatCmp::absolute>(potentialDiffNw, 0.0, 1.0e-30)) ? rhoMeanNw : density_[nPhaseIdx];
1043 entry[matrix] = (lambdaW + lambdaNw) * scalarPerm / dist * faceArea;
1044 entry[rhs] = entry[matrix] * pressBound;
1049 Scalar areaScaling = (unitOuterNormal * distVec);
1051 entry[rhs] -= (lambdaW * density_[wPhaseIdx] + lambdaNw * density_[nPhaseIdx]) * scalarPerm * (gravity_ * distVec)
1052 * faceArea * areaScaling;
1054 if (pressureType_ == pw)
1057 entry[rhs] -= 0.5 * (lambdaNwI + lambdaNwBound) * scalarPerm * (pcI - pcBound) / dist * faceArea;
1059 else if (pressureType_ == pn)
1062 entry[rhs] += 0.5 * (lambdaWI + lambdaWBound) * scalarPerm * (pcI - pcBound) / dist * faceArea;
1066 else if (bcType.isNeumann(eqIdxPress))
1068 problem_.neumann(boundValues, intersection);
1070 if (!compressibility_)
1072 boundValues[wPhaseIdx] /= density_[wPhaseIdx];
1073 boundValues[nPhaseIdx] /= density_[nPhaseIdx];
1075 entry[rhs] = -(boundValues[wPhaseIdx] + boundValues[nPhaseIdx]) * faceArea;
1079 DUNE_THROW(Dune::NotImplemented,
"No valid boundary condition type defined for pressure equation!");
1091template<
class TypeTag>
1094 for (
const auto& element : elements(problem_.gridView()))
1096 int eIdxGlobal = problem_.variables().index(element);
1098 CellData& cellData = problem_.variables().cellData(eIdxGlobal);
1100 const Scalar
temperature = problem_.temperature(element);
1103 const Scalar satW = cellData.saturation(wPhaseIdx);
1105 const auto fluidMatrixInteraction = problem_.spatialParams().fluidMatrixInteractionAtPos(element.geometry().center());
1106 const Scalar pc = fluidMatrixInteraction.pc(satW);
1111 if (pressureType_ == pw)
1113 pressW = cellData.pressure(wPhaseIdx);
1114 pressNw = pressW + pc;
1116 else if (pressureType_ == pn)
1118 pressNw = cellData.pressure(nPhaseIdx);
1119 pressW = pressNw - pc;
1122 if (compressibility_)
1124 FluidState& fluidState = cellData.fluidState();
1127 fluidState.setPressure(wPhaseIdx, pressW);
1128 fluidState.setPressure(nPhaseIdx, pressNw);
1137 fluidState.setDensity(wPhaseIdx, density_[wPhaseIdx]);
1138 fluidState.setDensity(nPhaseIdx, density_[nPhaseIdx]);
1141 fluidState.setViscosity(wPhaseIdx, viscosity_[wPhaseIdx]);
1142 fluidState.setViscosity(nPhaseIdx, viscosity_[nPhaseIdx]);
1146 cellData.setCapillaryPressure(pc);
1148 if (pressureType_ != pGlobal)
1150 cellData.setPressure(wPhaseIdx, pressW);
1151 cellData.setPressure(nPhaseIdx, pressNw);
1156 Scalar mobilityW = fluidMatrixInteraction.krw(satW) / viscosity_[wPhaseIdx];
1157 Scalar mobilityNw = fluidMatrixInteraction.krn(satW) / viscosity_[nPhaseIdx];
1159 if (compressibility_)
1161 mobilityW *= density_[wPhaseIdx];
1162 mobilityNw *= density_[nPhaseIdx];
1166 cellData.setMobility(wPhaseIdx, mobilityW);
1167 cellData.setMobility(nPhaseIdx, mobilityNw);
1170 cellData.setFracFlowFunc(wPhaseIdx, mobilityW / (mobilityW + mobilityNw));
1171 cellData.setFracFlowFunc(nPhaseIdx, mobilityNw / (mobilityW + mobilityNw));
1173 const Scalar gravityDiff = (problem_.bBoxMax() - element.geometry().center()) * gravity_;
1175 Scalar potW = pressW + gravityDiff * density_[wPhaseIdx];
1176 Scalar potNw = pressNw + gravityDiff * density_[nPhaseIdx];
1178 if (pressureType_ == pGlobal)
1180 potW = cellData.globalPressure() - cellData.fracFlowFunc(nPhaseIdx) * pc + gravityDiff * density_[wPhaseIdx];
1181 potNw = cellData.globalPressure() - cellData.fracFlowFunc(wPhaseIdx) * pc + gravityDiff * density_[nPhaseIdx];
1184 cellData.setPotential(wPhaseIdx, potW);
1185 cellData.setPotential(nPhaseIdx, potNw);
typename Properties::Detail::GetPropImpl< TypeTag, Property >::type GetProp
get the type of a property
Definition: propertysystem.hh:141
typename Properties::Detail::GetPropImpl< TypeTag, Property >::type::type GetPropType
get the type alias defined in the property
Definition: propertysystem.hh:150
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
Scalar volume(Shape shape, Scalar inscribedRadius)
Returns the volume of a given geometry based on the inscribed radius.
Definition: poreproperties.hh:73
Finite Volume discretization of a two-phase flow pressure equation of the sequential IMPES model.
Definition: 2p/sequential/diffusion/cellcentered/pressure.hh:113
void storePressureSolution(const Element &element)
Stores the pressure solution of a cell.
Definition: 2p/sequential/diffusion/cellcentered/pressure.hh:336
void storePressureSolution()
Globally stores the pressure solution.
Definition: 2p/sequential/diffusion/cellcentered/pressure.hh:320
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:719
FVPressure2P(Problem &problem)
Constructs a FVPressure2P object.
Definition: 2p/sequential/diffusion/cellcentered/pressure.hh:545
void updateMaterialLaws()
Updates and stores constitutive relations.
Definition: 2p/sequential/diffusion/cellcentered/pressure.hh:1092
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:843
void initialize(bool solveTwice=true)
Initializes the pressure model.
Definition: 2p/sequential/diffusion/cellcentered/pressure.hh:199
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:611
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:655
void addOutputVtkFields(MultiWriter &writer)
Adds pressure output to the output file.
Definition: 2p/sequential/diffusion/cellcentered/pressure.hh:414
void updateVelocity()
Velocity update.
Definition: 2p/sequential/diffusion/cellcentered/pressure.hh:306
void update()
Pressure update.
Definition: 2p/sequential/diffusion/cellcentered/pressure.hh:262
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.